Skip to content

Commit 12f7b03

Browse files
kyle-ssgZaimwa9pre-commit-ci[bot]claude
authored
chore: playwright (#6562)
Co-authored-by: Zaimwa9 <wadii.zaim@flagsmith.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent eddafb5 commit 12f7b03

92 files changed

Lines changed: 5390 additions & 5155 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/e2e-tests/action.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,26 @@ runs:
2626
node-version-file: frontend/.nvmrc
2727
cache-dependency-path: frontend/package-lock.json
2828

29+
- name: Cache Playwright browsers
30+
uses: actions/cache@v4
31+
with:
32+
path: ~/.cache/ms-playwright
33+
key: ${{ runner.os }}-playwright-${{ hashFiles('frontend/package-lock.json') }}
34+
restore-keys: |
35+
${{ runner.os }}-playwright-
36+
2937
- name: NPM Install
3038
working-directory: frontend
3139
run: |
3240
npm ci
3341
shell: bash
3442

35-
- name: Test with Chromedriver
43+
- name: Install Playwright browsers
44+
working-directory: frontend
45+
run: npm run test:install
46+
shell: bash
47+
48+
- name: Run E2E tests
3649
uses: nick-fields/retry@v3
3750
with:
3851
shell: bash

.github/workflows/.reusable-docker-e2e-tests.yml

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
required: true
1515
args:
1616
type: string
17-
description: Additional arguments to testcafe
17+
description: Additional arguments to playwright
1818
required: false
1919
default: ''
2020
concurrency:
@@ -44,6 +44,7 @@ jobs:
4444
contents: read
4545
packages: read
4646
id-token: write
47+
pull-requests: write
4748

4849
env:
4950
GCR_TOKEN: ${{ secrets.GCR_TOKEN }}
@@ -52,6 +53,17 @@ jobs:
5253
- name: Cloning repo
5354
uses: actions/checkout@v5
5455

56+
- name: Determine test type
57+
id: test-type
58+
run: |
59+
if [[ '${{ inputs.args }}' == *"@enterprise"* ]]; then
60+
echo "type=private-cloud" >> $GITHUB_OUTPUT
61+
echo "label=private-cloud" >> $GITHUB_OUTPUT
62+
else
63+
echo "type=oss" >> $GITHUB_OUTPUT
64+
echo "label=oss" >> $GITHUB_OUTPUT
65+
fi
66+
5567
- name: Login to Github Container Registry
5668
if: ${{ env.GCR_TOKEN }}
5769
uses: docker/login-action@v3
@@ -67,22 +79,79 @@ jobs:
6779
run: depot pull-token | docker login -u x-token --password-stdin registry.depot.dev
6880

6981
- name: Run tests on dockerised frontend
70-
uses: nick-fields/retry@v3
71-
with:
72-
shell: bash
73-
command: |
74-
cd frontend
75-
make test
76-
max_attempts: 2
77-
retry_on: error
78-
timeout_minutes: 20
79-
on_retry_command: |
80-
cd frontend
81-
docker compose down --remove-orphans || true
82+
working-directory: frontend
83+
run: make test
8284
env:
8385
opts: ${{ inputs.args }}
8486
API_IMAGE: ${{ inputs.api-image }}
8587
E2E_IMAGE: ${{ inputs.e2e-image }}
8688
E2E_CONCURRENCY: ${{ inputs.concurrency }}
89+
E2E_RETRIES: 2
8790
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
8891
GITHUB_ACTION_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
92+
timeout-minutes: 20
93+
94+
- name: Cleanup E2E services
95+
if: always()
96+
working-directory: frontend
97+
run: docker compose down --remove-orphans || true
98+
99+
- name: Copy results.json to HTML report
100+
if: always()
101+
run: |
102+
cp frontend/e2e/test-results/results.json frontend/e2e/playwright-report/ || true
103+
104+
- name: Upload HTML report
105+
if: failure()
106+
uses: actions/upload-artifact@v4
107+
with:
108+
name: playwright-html-report-${{ steps.test-type.outputs.type }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ strategy.job-index }}
109+
path: frontend/e2e/playwright-report/
110+
retention-days: 30
111+
if-no-files-found: warn
112+
113+
- name: Set artifact URL
114+
if: failure() && github.event_name == 'pull_request'
115+
id: artifact-url
116+
run: |
117+
echo "url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts" >> $GITHUB_OUTPUT
118+
119+
- name: Send Slack notification and upload report
120+
if: failure()
121+
working-directory: frontend
122+
run: |
123+
cd e2e
124+
zip -r playwright-report.zip playwright-report/ || echo "Failed to zip report"
125+
cd ..
126+
npm install --no-save @slack/web-api
127+
npx -y tsx e2e/slack-e2e-reporter.ts
128+
env:
129+
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
130+
GITHUB_ACTION_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
131+
GITHUB_REF_NAME: ${{ github.ref_name }}
132+
GITHUB_HEAD_REF: ${{ github.head_ref }}
133+
TEST_TYPE: ${{ steps.test-type.outputs.label }}
134+
PR_NUMBER: ${{ github.event.pull_request.number }}
135+
PR_TITLE: ${{ github.event.pull_request.title }}
136+
PR_URL: ${{ github.event.pull_request.html_url }}
137+
138+
- name: Comment PR with test results (success)
139+
if: success() && github.event_name == 'pull_request'
140+
uses: daun/playwright-report-summary@v3
141+
with:
142+
report-file: frontend/e2e/playwright-report/results.json
143+
comment-title: 'Playwright Test Results (${{ steps.test-type.outputs.label }} - ${{ inputs.runs-on }})'
144+
report-tag: 'playwright-${{ steps.test-type.outputs.label }}-${{ inputs.runs-on }}'
145+
custom-info: |
146+
**🔄 Run:** [#${{ github.run_number }} (attempt ${{ github.run_attempt }})](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
147+
148+
- name: Comment PR with test results (failure)
149+
if: failure() && github.event_name == 'pull_request'
150+
uses: daun/playwright-report-summary@v3
151+
with:
152+
report-file: frontend/e2e/playwright-report/results.json
153+
comment-title: 'Playwright Test Results (${{ steps.test-type.outputs.label }} - ${{ inputs.runs-on }})'
154+
report-tag: 'playwright-${{ steps.test-type.outputs.label }}-${{ inputs.runs-on }}'
155+
custom-info: |
156+
**📦 Artifacts:** [View test results and HTML report](${{ steps.artifact-url.outputs.url }})
157+
**🔄 Run:** [#${{ github.run_number }} (attempt ${{ github.run_attempt }})](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})

.github/workflows/frontend-test-staging.yml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,6 @@ jobs:
1515
- name: Cloning repo
1616
uses: actions/checkout@v5
1717

18-
# Temporarily install Firefox 143.0 to avoid test failures as superior versions cause frontend e2e tests to hang
19-
# To be removed once upstream issue correctly resolved
20-
- name: Install Firefox 143.0
21-
run: |
22-
sudo apt-get remove -y firefox || true
23-
sudo rm -rf /usr/bin/firefox /usr/lib/firefox*
24-
25-
ARCH=$(uname -m)
26-
wget -O /tmp/firefox.tar.xz "https://ftp.mozilla.org/pub/firefox/releases/143.0/linux-${ARCH}/en-US/firefox-143.0.tar.xz"
27-
sudo tar -xJf /tmp/firefox.tar.xz -C /opt
28-
sudo ln -s /opt/firefox/firefox /usr/local/bin/firefox
29-
rm /tmp/firefox.tar.xz
30-
31-
firefox --version
32-
33-
3418
- name: Run E2E tests against staging
3519
uses: ./.github/actions/e2e-tests
3620
with:

.github/workflows/platform-docker-build-e2e-image.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

.github/workflows/platform-pull-request.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ jobs:
150150
runs-on: ${{ matrix.runs-on }}
151151
e2e-image: ${{ needs.docker-build-e2e.outputs.image }}
152152
api-image: ${{ needs.docker-build-api.outputs.image }}
153-
args: --meta-filter category=oss
153+
args: --grep @oss
154154
secrets:
155155
GCR_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.GITHUB_TOKEN || '' }}
156156
SLACK_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.SLACK_TOKEN || '' }}
@@ -167,7 +167,7 @@ jobs:
167167
runs-on: ${{ matrix.runs-on }}
168168
e2e-image: ${{ needs.docker-build-e2e.outputs.image }}
169169
api-image: ${{ needs.docker-build-private-cloud.outputs.image }}
170-
args: --meta-filter category=oss,category=enterprise
170+
args: --grep "@oss|@enterprise"
171171
secrets:
172172
GCR_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.GITHUB_TOKEN || '' }}
173173
SLACK_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.SLACK_TOKEN || '' }}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# E2E Test Creator
2+
3+
Create a new E2E test following the existing patterns in the codebase.
4+
5+
## Arguments
6+
7+
- `$ARGUMENTS` = "" → Ask the user what to test
8+
- `$ARGUMENTS` = "segment creation flow" → Create a test for that feature
9+
10+
## CRITICAL: Read Context First
11+
12+
**You MUST read `.claude/context/e2e.md` before proceeding.** It contains essential configuration, test structure, and debugging guides.
13+
14+
## Workflow
15+
16+
1. **Determine what to test:**
17+
- If `$ARGUMENTS` is provided, use that as the test description
18+
- Otherwise, ask the user what feature/page/flow to test
19+
20+
2. **Determine if OSS or Enterprise:**
21+
- Check if the feature exists in enterprise-only code paths
22+
- Tag the test with `@oss` or `@enterprise` accordingly
23+
24+
3. **Review existing patterns:**
25+
- Read 2-3 similar test files from `frontend/e2e/tests/`
26+
- Read `frontend/e2e/helpers.playwright.ts` for available utilities
27+
28+
4. **Scan application code:**
29+
- Find components being tested in `frontend/web/components/` or `frontend/common/`
30+
- Add `data-test` attributes if missing
31+
32+
5. **Create the test file:**
33+
- Follow naming convention: `*-test.pw.ts` or `*-tests.pw.ts`
34+
- Use helper functions from `helpers.playwright.ts`
35+
36+
6. **Verify the test works:**
37+
```bash
38+
SKIP_BUNDLE=1 E2E_CONCURRENCY=1 npm run test -- tests/new-test.pw.ts --quiet
39+
```
40+
Run twice to check for flakiness. On failure, follow the analysis workflow in context/e2e.md.
41+
42+
7. **Report what was created:**
43+
- Test file path
44+
- Any `data-test` attributes added
45+
- Test stability results
46+
47+
## Important Notes
48+
49+
- Always use `data-test` attributes for selectors
50+
- Use existing helper functions instead of raw Playwright APIs
51+
- Tests should be independent and not rely on execution order
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# E2E Enterprise Test Runner
2+
3+
Run enterprise E2E tests (tagged with @enterprise) and report results.
4+
5+
## Arguments
6+
7+
- `$ARGUMENTS` = "" → Run tests once (default)
8+
- `$ARGUMENTS` = "5" → Run tests 5 times, stopping on first failure
9+
10+
## CRITICAL: Read Context First
11+
12+
**You MUST read `.claude/context/e2e.md` before proceeding.** It contains essential configuration, failure analysis workflows, and fix patterns.
13+
14+
## Run Command
15+
16+
```bash
17+
E2E_RETRIES=0 SKIP_BUNDLE=1 E2E_CONCURRENCY=20 npm run test -- --grep @enterprise --quiet
18+
```
19+
20+
## Re-running Failed Enterprise Tests
21+
22+
When re-running specific failed tests, include the grep flag:
23+
```bash
24+
E2E_RETRIES=0 SKIP_BUNDLE=1 E2E_CONCURRENCY=1 npm run test -- tests/specific-test.pw.ts --grep @enterprise
25+
```
26+
27+
## Workflow
28+
29+
1. Run tests (one iteration at a time if multiple requested)
30+
2. On failure: follow the failure analysis workflow in context/e2e.md
31+
3. Report results
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# E2E OSS Test Runner
2+
3+
Run OSS (non-enterprise) E2E tests and report results.
4+
5+
## Arguments
6+
7+
- `$ARGUMENTS` = "" → Run tests once (default)
8+
- `$ARGUMENTS` = "5" → Run tests 5 times, stopping on first failure
9+
10+
## CRITICAL: Read Context First
11+
12+
**You MUST read `.claude/context/e2e.md` before proceeding.** It contains essential configuration, failure analysis workflows, and fix patterns.
13+
14+
## Run Command
15+
16+
```bash
17+
E2E_RETRIES=0 SKIP_BUNDLE=1 E2E_CONCURRENCY=20 npm run test -- --grep @oss --quiet
18+
```
19+
20+
## Workflow
21+
22+
1. Run tests (one iteration at a time if multiple requested)
23+
2. On failure: follow the failure analysis workflow in context/e2e.md
24+
3. Report results

frontend/.claude/commands/e2e.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# E2E Test Runner (All Tests)
2+
3+
Run all E2E tests (both OSS and enterprise) and report results.
4+
5+
## Arguments
6+
7+
- `$ARGUMENTS` = "" → Run tests once (default)
8+
- `$ARGUMENTS` = "5" → Run tests 5 times, stopping on first failure
9+
10+
## CRITICAL: Read Context First
11+
12+
**You MUST read `.claude/context/e2e.md` before proceeding.** It contains essential configuration, failure analysis workflows, and fix patterns.
13+
14+
## Run Command
15+
16+
```bash
17+
E2E_RETRIES=0 SKIP_BUNDLE=1 E2E_CONCURRENCY=20 npm run test -- --grep "@oss|@enterprise" --quiet
18+
```
19+
20+
## Workflow
21+
22+
1. Run tests (one iteration at a time if multiple requested)
23+
2. On failure: follow the failure analysis workflow in context/e2e.md
24+
3. Report results with pass/fail counts for OSS and enterprise tests

0 commit comments

Comments
 (0)