chore: Add some tests
All checks were successful
Pull Request Labeler / labeler (pull_request_target) Successful in 5s
CI / Get Changed Files (pull_request) Successful in 11s
Label PRs based on size / Check PR size (pull_request) Successful in 11s
Claude PR Review / claude-code (pull_request) Successful in 33s
CI / eslint (pull_request) Successful in 40s
CI / oxlint (pull_request) Successful in 46s
CI / prettier (pull_request) Successful in 50s
CI / Docker backend validation (pull_request) Successful in 34s
CI / Docker frontend validation (pull_request) Successful in 1m27s
CI / test-build (pull_request) Successful in 1m32s
CI / Checkstyle Main (pull_request) Successful in 1m43s
CI / Backend Tests (pull_request) Successful in 2m31s
CI / Playwright (pull_request) Successful in 2m18s
All checks were successful
Pull Request Labeler / labeler (pull_request_target) Successful in 5s
CI / Get Changed Files (pull_request) Successful in 11s
Label PRs based on size / Check PR size (pull_request) Successful in 11s
Claude PR Review / claude-code (pull_request) Successful in 33s
CI / eslint (pull_request) Successful in 40s
CI / oxlint (pull_request) Successful in 46s
CI / prettier (pull_request) Successful in 50s
CI / Docker backend validation (pull_request) Successful in 34s
CI / Docker frontend validation (pull_request) Successful in 1m27s
CI / test-build (pull_request) Successful in 1m32s
CI / Checkstyle Main (pull_request) Successful in 1m43s
CI / Backend Tests (pull_request) Successful in 2m31s
CI / Playwright (pull_request) Successful in 2m18s
This commit is contained in:
parent
551f5bcf2e
commit
e828efdfa7
13 changed files with 224 additions and 15 deletions
|
@ -165,6 +165,46 @@ jobs:
|
|||
cd frontend
|
||||
bun run lint
|
||||
|
||||
playwright:
|
||||
runs-on: ubuntu-latest
|
||||
name: Playwright
|
||||
needs: changed_files
|
||||
container:
|
||||
image: git.kjan.de/actions/runner-casino-playwright:latest
|
||||
if: ${{ needs.changed_files.outputs.frontend == 'true' || needs.changed_files.outputs.workflow == 'true' }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: "temurin" # See 'Supported distributions' for available options
|
||||
java-version: "23"
|
||||
- name: Install bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
- uses: actions/cache@v4
|
||||
working-directory: ./frontend
|
||||
with:
|
||||
path: |
|
||||
frontend/node_modules/
|
||||
key: ${{ runner.os }}-bun-
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bun-
|
||||
- run: bun add -g concurrently
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd frontend
|
||||
bun install
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.12
|
||||
working-directory: ./frontend
|
||||
- name: Run Playwright tests
|
||||
env:
|
||||
CI: true
|
||||
SPRING_PROFILES_ACTIVE: inmemory
|
||||
working-directory: ./frontend
|
||||
run: bash -c "source $HOME/.cargo/env && bunx playwright test"
|
||||
|
||||
oxlint:
|
||||
runs-on: docker
|
||||
name: oxlint
|
||||
|
|
|
@ -55,6 +55,7 @@ dependencies {
|
|||
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
|
||||
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")
|
||||
implementation("org.springframework.boot:spring-boot-starter-mail")
|
||||
runtimeOnly("com.h2database:h2")
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
|
|
|
@ -49,33 +49,32 @@ public class CasinoApplication {
|
|||
lootBoxRepository.saveAll(Arrays.asList(basicLootBox, premiumLootBox));
|
||||
|
||||
RewardEntity commonReward = new RewardEntity();
|
||||
commonReward.setValue(new BigDecimal("0.50"));
|
||||
commonReward.setRewardValue(new BigDecimal("0.50"));
|
||||
commonReward.setProbability(new BigDecimal("0.7"));
|
||||
|
||||
RewardEntity rareReward = new RewardEntity();
|
||||
rareReward.setValue(new BigDecimal("2.00"));
|
||||
rareReward.setRewardValue(new BigDecimal("2.00"));
|
||||
rareReward.setProbability(new BigDecimal("0.25"));
|
||||
|
||||
RewardEntity epicReward = new RewardEntity();
|
||||
epicReward.setValue(new BigDecimal("5.00"));
|
||||
epicReward.setRewardValue(new BigDecimal("5.00"));
|
||||
epicReward.setProbability(new BigDecimal("0.5"));
|
||||
|
||||
RewardEntity premiumCommon = new RewardEntity();
|
||||
premiumCommon.setValue(new BigDecimal("2.00"));
|
||||
premiumCommon.setRewardValue(new BigDecimal("2.00"));
|
||||
premiumCommon.setProbability(new BigDecimal("0.6"));
|
||||
|
||||
RewardEntity premiumRare = new RewardEntity();
|
||||
premiumRare.setValue(new BigDecimal("5.00"));
|
||||
premiumRare.setRewardValue(new BigDecimal("5.00"));
|
||||
premiumRare.setProbability(new BigDecimal("0.3"));
|
||||
|
||||
RewardEntity legendaryReward = new RewardEntity();
|
||||
legendaryReward.setValue(new BigDecimal("15.00"));
|
||||
legendaryReward.setRewardValue(new BigDecimal("15.00"));
|
||||
legendaryReward.setProbability(new BigDecimal("0.10"));
|
||||
|
||||
rewardRepository.saveAll(Arrays.asList(
|
||||
commonReward, rareReward, epicReward,
|
||||
premiumCommon, premiumRare, legendaryReward
|
||||
));
|
||||
premiumCommon, premiumRare, legendaryReward));
|
||||
|
||||
basicLootBox.getRewards().add(commonReward);
|
||||
basicLootBox.getRewards().add(premiumRare);
|
||||
|
|
|
@ -34,7 +34,7 @@ public class LootBoxService {
|
|||
|
||||
public void handleBalance(UserEntity user, LootBoxEntity lootBox, RewardEntity reward) {
|
||||
user.setBalance(user.getBalance().subtract(lootBox.getPrice()));
|
||||
user.setBalance(user.getBalance().add(reward.getValue()));
|
||||
user.setBalance(user.getBalance().add(reward.getRewardValue()));
|
||||
userRepository.save(user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.util.List;
|
|||
public class RewardEntity {
|
||||
|
||||
public RewardEntity(BigDecimal value, BigDecimal probability) {
|
||||
this.value = value;
|
||||
this.rewardValue = value;
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class RewardEntity {
|
|||
private Long id;
|
||||
|
||||
@Column(precision = 19, scale = 2)
|
||||
private BigDecimal value;
|
||||
private BigDecimal rewardValue;
|
||||
|
||||
@Column(precision = 5, scale = 2)
|
||||
private BigDecimal probability;
|
||||
|
|
58
backend/src/main/resources/application-inmemory.properties
Normal file
58
backend/src/main/resources/application-inmemory.properties
Normal file
|
@ -0,0 +1,58 @@
|
|||
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
|
||||
server.port=${HTTP_PORT:8080}
|
||||
stripe.secret.key=${STRIPE_SECRET_KEY:sk_test_51QrePYIvCfqz7ANgqam8rEwWcMeKiLOof3j6SCMgu2sl4sESP45DJxca16mWcYo1sQaiBv32CMR6Z4AAAGQPCJo300ubuZKO8I}
|
||||
stripe.webhook.secret=${STRIPE_WEBHOOK_SECRET:whsec_746b6a488665f6057118bdb4a2b32f4916f16c277109eeaed5e8f8e8b81b8c15}
|
||||
|
||||
app.frontend-host=${FE_URL:http://localhost:4200}
|
||||
|
||||
app.mail.authentication=${MAIL_AUTHENTICATION:false}
|
||||
app.mail.host=${MAIL_HOST:localhost}
|
||||
app.mail.port=${MAIL_PORT:1025}
|
||||
app.mail.username=${MAIL_USER:null}
|
||||
app.mail.password=${MAIL_PASS:null}
|
||||
app.mail.from-address=${MAIL_FROM:casino@localhost}
|
||||
app.mail.protocol=${MAIL_PROTOCOL:smtp}
|
||||
|
||||
spring.application.name=casino
|
||||
|
||||
# JWT Configuration
|
||||
jwt.secret=${JWT_SECRET:5367566B59703373367639792F423F4528482B4D6251655468576D5A71347437}
|
||||
jwt.expiration.ms=${JWT_EXPIRATION_MS:86400000}
|
||||
|
||||
# Logging
|
||||
logging.level.org.springframework.security=DEBUG
|
||||
|
||||
# Swagger
|
||||
springdoc.swagger-ui.path=swagger
|
||||
springdoc.swagger-ui.try-it-out-enabled=true
|
||||
|
||||
# GitHub OAuth2 Configuration
|
||||
spring.security.oauth2.client.registration.github.client-id=${GITHUB_CLIENT_ID:Ov23lingzZsPn1wwACoK}
|
||||
spring.security.oauth2.client.registration.github.client-secret=${GITHUB_CLIENT_SECRET:4b327fb3b1ab67584a03bcb9d53fa6439fbccad7}
|
||||
spring.security.oauth2.client.registration.github.redirect-uri=${app.frontend-host}/oauth2/callback/github
|
||||
spring.security.oauth2.client.registration.github.scope=user:email,read:user
|
||||
spring.security.oauth2.client.provider.github.authorization-uri=https://github.com/login/oauth/authorize
|
||||
spring.security.oauth2.client.provider.github.token-uri=https://github.com/login/oauth/access_token
|
||||
spring.security.oauth2.client.provider.github.user-info-uri=https://api.github.com/user
|
||||
spring.security.oauth2.client.provider.github.user-name-attribute=login
|
||||
|
||||
# OAuth Success and Failure URLs
|
||||
app.oauth2.authorizedRedirectUris=${app.frontend-host}/auth/oauth2/callback
|
||||
|
||||
# Google OAuth2 Configuration
|
||||
spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID:350791038883-c1r7v4o793itq8a0rh7dut7itm7uneam.apps.googleusercontent.com}
|
||||
spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_SECRET: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}
|
||||
spring.security.oauth2.client.registration.google.redirect-uri=${app.frontend-host}/oauth2/callback/google
|
||||
spring.security.oauth2.client.registration.google.scope=email,profile
|
||||
spring.security.oauth2.client.provider.google.authorization-uri=https://accounts.google.com/o/oauth2/v2/auth
|
||||
spring.security.oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token
|
||||
spring.security.oauth2.client.provider.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
|
||||
spring.security.oauth2.client.provider.google.user-name-attribute=sub
|
||||
|
3
frontend/.gitignore
vendored
3
frontend/.gitignore
vendored
|
@ -29,6 +29,9 @@ yarn-error.log
|
|||
.history/*
|
||||
|
||||
# Miscellaneous
|
||||
/.claude
|
||||
/test-results
|
||||
/playwright-report
|
||||
/.angular/cache
|
||||
.sass-cache/
|
||||
/connect.lock
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"@angular-devkit/build-angular": "^20.0.0",
|
||||
"@angular/cli": "^20.0.0",
|
||||
"@angular/compiler-cli": "^20.0.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"angular-eslint": "19.7.1",
|
||||
"eslint": "^9.28.0",
|
||||
|
@ -542,6 +543,8 @@
|
|||
|
||||
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
||||
|
||||
"@playwright/test": ["@playwright/test@1.52.0", "", { "dependencies": { "playwright": "1.52.0" }, "bin": { "playwright": "cli.js" } }, "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.40.2", "", { "os": "android", "cpu": "arm" }, "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.40.2", "", { "os": "android", "cpu": "arm64" }, "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw=="],
|
||||
|
@ -1082,7 +1085,7 @@
|
|||
|
||||
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
"fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
|
@ -1514,6 +1517,10 @@
|
|||
|
||||
"piscina": ["piscina@5.0.0", "", { "optionalDependencies": { "@napi-rs/nice": "^1.0.1" } }, "sha512-R+arufwL7sZvGjAhSMK3TfH55YdGOqhpKXkcwQJr432AAnJX/xxX19PA4QisrmJ+BTTfZVggaz6HexbkQq1l1Q=="],
|
||||
|
||||
"playwright": ["playwright@1.52.0", "", { "dependencies": { "playwright-core": "1.52.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw=="],
|
||||
|
||||
"playwright-core": ["playwright-core@1.52.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg=="],
|
||||
|
||||
"postcss": ["postcss@8.5.4", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w=="],
|
||||
|
||||
"postcss-loader": ["postcss-loader@8.1.1", "", { "dependencies": { "cosmiconfig": "^9.0.0", "jiti": "^1.20.0", "semver": "^7.5.4" }, "peerDependencies": { "@rspack/core": "0.x || 1.x", "postcss": "^7.0.0 || ^8.0.1", "webpack": "^5.0.0" }, "optionalPeers": ["@rspack/core", "webpack"] }, "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ=="],
|
||||
|
@ -2102,6 +2109,8 @@
|
|||
|
||||
"resolve-url-loader/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="],
|
||||
|
||||
"rollup/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"schema-utils/ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="],
|
||||
|
||||
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||
|
@ -2140,6 +2149,8 @@
|
|||
|
||||
"tar/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
||||
|
||||
"vite/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"vite/tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
|
||||
|
||||
"webpack/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
|
||||
|
@ -2266,6 +2277,8 @@
|
|||
|
||||
"karma-coverage/istanbul-lib-instrument/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"karma/chokidar/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"karma/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"karma/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
||||
|
@ -2306,6 +2319,8 @@
|
|||
|
||||
"tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||
|
||||
"webpack-dev-server/chokidar/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"webpack-dev-server/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"webpack-dev-server/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
||||
|
|
8
frontend/e2e/backend.spec.ts
Normal file
8
frontend/e2e/backend.spec.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('backend works', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/health');
|
||||
const response = await page.textContent('body');
|
||||
expect(response).toBeTruthy();
|
||||
expect(page.getByText('{"status":"UP"}')).toBeVisible();
|
||||
});
|
36
frontend/e2e/homepage.spec.ts
Normal file
36
frontend/e2e/homepage.spec.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('home page loads correctly', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
await expect(page).toHaveTitle(/Casino/);
|
||||
await expect(page.getByRole('heading', { name: 'Willkommensbonus' })).toBeVisible();
|
||||
await expect(page.getByText('von bis zu €')).toBeVisible();
|
||||
});
|
||||
|
||||
test('registration popup should open and close', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Registrieren' }).click();
|
||||
|
||||
await expect(page.getByText('Konto erstellenE-')).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Dialog schließen' }).click();
|
||||
|
||||
await expect(page.getByText('Konto erstellenE-')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('registration should work', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Registrieren' }).click();
|
||||
|
||||
await page.getByRole('textbox', { name: 'E-Mail' }).fill('test@kjan.email');
|
||||
await page.getByRole('textbox', { name: 'Benutzername' }).fill('test-playwright');
|
||||
await page.getByRole('textbox', { name: 'Passwort' }).fill('BananaMan123');
|
||||
await page.locator('form').getByRole('button', { name: 'Registrieren' }).click();
|
||||
await page.getByRole('button', { name: 'Dialog schließen' }).click();
|
||||
await page.getByRole('navigation').getByRole('button', { name: 'Anmelden' }).click();
|
||||
await page.getByRole('textbox', { name: 'Benutzername oder E-Mail' }).fill('test@kjan.email');
|
||||
await page.getByRole('textbox', { name: 'Passwort' }).fill('BananaMan123');
|
||||
await page.locator('form').getByRole('button', { name: 'Anmelden' }).click();
|
||||
await expect(page.getByText('Email not verified')).toBeVisible();
|
||||
});
|
|
@ -39,9 +39,10 @@
|
|||
"tslib": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler-cli": "^20.0.0",
|
||||
"@angular-devkit/build-angular": "^20.0.0",
|
||||
"@angular/cli": "^20.0.0",
|
||||
"@angular/compiler-cli": "^20.0.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"angular-eslint": "19.7.1",
|
||||
"eslint": "^9.28.0",
|
||||
|
|
49
frontend/playwright.config.ts
Normal file
49
frontend/playwright.config.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
// playwright.config.ts (or .js)
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './e2e',
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
// This baseURL is for your frontend tests.
|
||||
// Tests hitting the backend directly will use absolute URLs.
|
||||
baseURL: 'http://localhost:4200',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
},
|
||||
],
|
||||
|
||||
webServer: {
|
||||
command:
|
||||
'cd .. && conc -n "frontend,backend" "cd frontend && bun run start" "cd backend/ && watchexec -r -e java ./gradlew :bootRun"',
|
||||
// **IMPORTANT CHANGE HERE:**
|
||||
// Point to your backend's health check endpoint.
|
||||
// If your Spring Boot app uses Actuator, it might be /actuator/health
|
||||
// Verify the correct health endpoint for your backend.
|
||||
url: 'http://localhost:8080/health', // Or "http://localhost:8080/actuator/health"
|
||||
reuseExistingServer: !process.env.CI,
|
||||
// **INCREASE TIMEOUT SIGNIFICANTLY**
|
||||
// Gradle + Spring Boot can take a while, especially on first run or in CI.
|
||||
// Adjust as needed, e.g., 3-5 minutes.
|
||||
timeout: 300 * 1000, // 300 seconds = 5 minutes
|
||||
stdout: 'pipe', // Good for capturing logs in CI reports
|
||||
stderr: 'pipe',
|
||||
// Optional: If your server needs specific environment variables
|
||||
// env: {
|
||||
// SPRING_PROFILES_ACTIVE: 'test', // Example for Spring Boot
|
||||
// },
|
||||
},
|
||||
});
|
3
justfile
3
justfile
|
@ -6,8 +6,7 @@ info:
|
|||
start:
|
||||
command -v concurrently &> /dev/null || bun add -g concurrently
|
||||
command -v watchexec &> /dev/null || brew install watchexec
|
||||
docker compose up -d
|
||||
conc -n "frontend,backend" "cd frontend && bun run start" "cd backend/ && watchexec -r -e java ./gradlew :bootRun"
|
||||
conc -n "frontend,backend,docker" "cd frontend && bun run start" "cd backend/ && watchexec -r -e java ./gradlew :bootRun" "docker compose up"
|
||||
|
||||
# Builds both the backend and frontend docker images (obv)
|
||||
build:
|
||||
|
|
Reference in a new issue