Skip to content

Commit 507bd07

Browse files
Merge pull request #1 from co-cddo/f-playwright
feat: wrangle playwright tests into shape
2 parents 6db34c7 + ee41de9 commit 507bd07

17 files changed

Lines changed: 478 additions & 81 deletions

.github/workflows/ci.yml

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,49 @@ on:
1010

1111
permissions:
1212
contents: read
13-
packages: write
14-
id-token: write
15-
attestations: write
13+
pull-requests: read
1614

1715
jobs:
1816
gitleaks:
1917
runs-on: ubuntu-latest
2018
steps:
21-
- uses: actions/checkout@v4
19+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
2220
with:
2321
fetch-depth: 0
24-
- uses: gitleaks/gitleaks-action@v2
22+
persist-credentials: false
23+
- uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2
2524
env:
2625
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2726
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
2827

28+
zizmor:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
32+
with:
33+
persist-credentials: false
34+
- uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
35+
with:
36+
advanced-security: false
37+
2938
commitlint:
3039
if: github.event_name == 'pull_request'
3140
runs-on: ubuntu-latest
3241
steps:
33-
- uses: actions/checkout@v4
42+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
3443
with:
3544
fetch-depth: 0
36-
- uses: wagoid/commitlint-github-action@v6
45+
persist-credentials: false
46+
- uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6
3747

3848
lint:
3949
runs-on: ubuntu-latest
4050
steps:
41-
- uses: actions/checkout@v4
42-
- uses: pnpm/action-setup@v4
43-
- uses: actions/setup-node@v4
51+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
52+
with:
53+
persist-credentials: false
54+
- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
55+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
4456
with:
4557
node-version-file: .nvmrc
4658
cache: pnpm
@@ -50,9 +62,11 @@ jobs:
5062
test:
5163
runs-on: ubuntu-latest
5264
steps:
53-
- uses: actions/checkout@v4
54-
- uses: pnpm/action-setup@v4
55-
- uses: actions/setup-node@v4
65+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
66+
with:
67+
persist-credentials: false
68+
- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
69+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
5670
with:
5771
node-version-file: .nvmrc
5872
cache: pnpm
@@ -63,9 +77,11 @@ jobs:
6377
runs-on: ubuntu-latest
6478
timeout-minutes: 60
6579
steps:
66-
- uses: actions/checkout@v4
80+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
81+
with:
82+
persist-credentials: false
6783
- run: docker compose --profile test up e2e-test --build --abort-on-container-exit
68-
- uses: actions/upload-artifact@v4
84+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
6985
if: always()
7086
with:
7187
name: playwright-report
@@ -75,16 +91,23 @@ jobs:
7591
build:
7692
needs: [lint, test, e2e]
7793
runs-on: ubuntu-latest
94+
permissions:
95+
contents: read
96+
packages: write
97+
id-token: write
98+
attestations: write
7899
steps:
79-
- uses: actions/checkout@v4
80-
- uses: docker/setup-buildx-action@v3
81-
- uses: docker/login-action@v3
100+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
101+
with:
102+
persist-credentials: false
103+
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
104+
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
82105
if: github.event_name == 'push'
83106
with:
84107
registry: ghcr.io
85108
username: ${{ github.actor }}
86109
password: ${{ secrets.GITHUB_TOKEN }}
87-
- uses: docker/build-push-action@v6
110+
- uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
88111
with:
89112
push: ${{ github.event_name == 'push' }}
90113
provenance: ${{ github.event_name == 'push' }}
@@ -97,13 +120,14 @@ jobs:
97120

98121
check:
99122
if: always()
100-
needs: [gitleaks, commitlint, lint, test, e2e, build]
123+
needs: [gitleaks, zizmor, commitlint, lint, test, e2e, build]
101124
runs-on: ubuntu-latest
102125
steps:
103126
- name: Verify all jobs passed
104127
run: |
105128
results=( \
106129
"${{ needs.gitleaks.result }}" \
130+
"${{ needs.zizmor.result }}" \
107131
"${{ needs.commitlint.result }}" \
108132
"${{ needs.lint.result }}" \
109133
"${{ needs.test.result }}" \

.github/workflows/release-please.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ jobs:
1212
release-please:
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: googleapis/release-please-action@v4
15+
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4
1616
with:
1717
release-type: node

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ playwright-report/
99
test-results/
1010
.DS_Store
1111
coverage/
12-
.nyc_output/
12+
.nyc_output/
13+
.pnpm-store/

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
npx lint-staged
22
gitleaks git --pre-commit --staged --verbose
3+
zizmor .github/

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ RUN apt-get update && apt-get install -y \
2727
libnss3 libnspr4 libdbus-1-3 libatk1.0-0 libatk-bridge2.0-0 \
2828
libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 \
2929
libxfixes3 libxrandr2 libgbm1 libasound2 \
30+
curl \
3031
&& rm -rf /var/lib/apt/lists/*
3132

3233
COPY --from=chromium /pw-browsers /pw-browsers

docker-compose.yml

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,59 @@ services:
1515
timeout: 5s
1616
retries: 5
1717

18-
app:
18+
oidc-mock:
19+
image: ghcr.io/navikt/mock-oauth2-server:2.1.10
20+
ports:
21+
- "8090:8090"
22+
environment:
23+
SERVER_PORT: "8090"
24+
JSON_CONFIG: |
25+
{
26+
"interactiveLogin": false,
27+
"tokenCallbacks": [{
28+
"issuerId": "default",
29+
"requestMappings": [{
30+
"requestParam": "scope",
31+
"match": "*",
32+
"claims": {
33+
"sub": "test-user",
34+
"email": "test@example.gov.uk",
35+
"email_verified": true,
36+
"display_name": "Test User",
37+
"name": "Test User"
38+
}
39+
}]
40+
}]
41+
}
42+
43+
compliance-scraper:
1944
build: .
2045
depends_on:
2146
postgres:
2247
condition: service_healthy
48+
oidc-mock:
49+
condition: service_started
2350
env_file:
24-
- .env
51+
- path: .env
52+
required: false
2553
environment:
2654
DATABASE_URL: postgres://scraper:scraper@postgres:5432/compliance_scraper
2755
AWS_REGION: eu-west-2
2856
BEDROCK_MODEL_ID: eu.anthropic.claude-haiku-4-5-20251001-v1:0
2957
SERVICES_JSON_PATH: /app/services.json
3058
SEED_DATABASE: "true"
3159
NODE_ENV: development
32-
APP_URL: http://localhost:3000
33-
NODE_EXTRA_CA_CERTS: /etc/ssl/cert.pem
34-
volumes:
35-
- ~/.aws:/home/node/.aws:ro
36-
- ./local/cert.pem:/etc/ssl/cert.pem:ro
60+
APP_URL: http://compliance-scraper:3000
61+
SSO_ISSUER: http://oidc-mock:8090/default
62+
SSO_CLIENT_ID: test-client
63+
SSO_CLIENT_SECRET: test-secret
3764
ports:
3865
- "3000:3000"
66+
healthcheck:
67+
test: curl -f http://localhost:3000/health || exit 1
68+
interval: 5s
69+
timeout: 5s
70+
retries: 5
3971

4072
adminer:
4173
image: adminer:latest
@@ -47,43 +79,16 @@ services:
4779
ports:
4880
- "8080:8080"
4981

50-
test-app:
51-
profiles: [test]
52-
build:
53-
context: .
54-
dockerfile: Dockerfile
55-
ports:
56-
- "3001:3000"
57-
depends_on:
58-
postgres:
59-
condition: service_healthy
60-
environment:
61-
DATABASE_HOST: postgres
62-
DATABASE_PORT: 5432
63-
DATABASE_USER: scraper
64-
DATABASE_PASSWORD: scraper
65-
DATABASE_NAME: compliance_scraper
66-
NODE_ENV: test
67-
SEED_DATABASE: "true"
68-
SERVICES_JSON_PATH: /app/services.json
69-
AWS_REGION: eu-west-2
70-
BEDROCK_MODEL_ID: eu.anthropic.claude-haiku-4-5-20251001-v1:0
71-
healthcheck:
72-
test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1:3000/health"]
73-
interval: 5s
74-
timeout: 5s
75-
retries: 10
76-
7782
e2e-test:
7883
profiles: [test]
79-
image: mcr.microsoft.com/playwright:v1.50.0-noble
84+
image: mcr.microsoft.com/playwright:v1.59.1-noble
8085
working_dir: /app
8186
depends_on:
82-
test-app:
87+
compliance-scraper:
8388
condition: service_healthy
8489
environment:
8590
CI: "true"
86-
PLAYWRIGHT_BASE_URL: http://test-app:3000
91+
PLAYWRIGHT_BASE_URL: http://compliance-scraper:3000
8792
volumes:
8893
- .:/app
8994
- e2e-node-modules:/app/node_modules

eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ import tseslint from 'typescript-eslint';
44
export default tseslint.config(
55
eslint.configs.recommended,
66
...tseslint.configs.recommended,
7-
{ ignores: ['dist/', 'node_modules/'] },
7+
{ ignores: ['dist/', 'node_modules/', 'playwright-report/', 'test-results/'] },
88
{ files: ['**/*.js'], languageOptions: { globals: { module: 'readonly', require: 'readonly' } } }
99
);

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"dev:watch": "nodemon --watch src --ext ts,njk --exec ts-node src/main.ts",
1616
"dev:server": "ts-node src/server/index.ts",
1717
"lint": "eslint .",
18-
"test": "echo 'No unit tests yet' && exit 0",
18+
"test": "node --require ts-node/register --test $(find tests/unit -name '*.test.ts')",
19+
"test:e2e": "playwright test",
1920
"db:migrate": "ts-node src/db/migrate.ts",
2021
"db:seed": "ts-node src/db/seed.ts",
2122
"fetch-services": "bash scripts/fetch-services.sh",
@@ -35,6 +36,7 @@
3536
},
3637
"devDependencies": {
3738
"@eslint/js": "^10.0.1",
39+
"@playwright/test": "^1.59.1",
3840
"@types/connect-pg-simple": "^7.0.3",
3941
"@types/express": "^4.17.25",
4042
"@types/express-session": "^1.19.0",

playwright.config.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// <reference types="node" />
2+
import { defineConfig } from "@playwright/test";
3+
4+
export default defineConfig({
5+
testDir: "./tests/e2e",
6+
fullyParallel: true,
7+
forbidOnly: !!process.env.CI,
8+
retries: process.env.CI ? 2 : 0,
9+
workers: process.env.CI ? 1 : undefined,
10+
reporter: "html",
11+
use: {
12+
baseURL: process.env.PLAYWRIGHT_BASE_URL || "http://localhost:3000",
13+
trace: "on-first-retry",
14+
},
15+
projects: [
16+
{
17+
name: "chromium",
18+
use: {},
19+
},
20+
],
21+
webServer: process.env.PLAYWRIGHT_BASE_URL
22+
? undefined
23+
: {
24+
command: "npm start",
25+
url: "http://localhost:3000/health",
26+
reuseExistingServer: !process.env.CI,
27+
},
28+
});

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)