Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,37 @@ jobs:
name: Run Jest tests
- codecov/upload

javascript-integration-tests:
executor:
name: node/default
tag: '22.0'
# 4 vCPU: Playwright runs spec files in parallel workers, and the rspack
# dev server build that `webServer` triggers benefits from the extra cores.
resource_class: large
steps:
- checkout
- setup-pnpm
- restore_cache:
keys:
- playwright-firefox-v1-{{ checksum "pnpm-lock.yaml" }}
- playwright-firefox-v1-
- run:
name: Install Playwright Firefox
command: npx playwright install --with-deps firefox
- save_cache:
key: playwright-firefox-v1-{{ checksum "pnpm-lock.yaml" }}
paths:
- ~/.cache/ms-playwright
- run:
name: Run Playwright integration tests
command: pnpm test:integration
- store_test_results:
path: test-results
- store_artifacts:
path: playwright-report
- store_artifacts:
path: test-results

javascript-lint:
executor:
name: node/default
Expand Down Expand Up @@ -257,6 +288,7 @@ workflows:
run-tests:
jobs:
- javascript-tests
- javascript-integration-tests
- javascript-lint
- builds
- python-tests-frontend
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ CLAUDE.md
.superpowers/

# Cloud SQL Auth Proxy
cloud-sql-proxy
cloud-sql-proxy
# Playwright artifacts
test-results/
playwright-report/
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"quoteStyle": "single",
"trailingCommas": "all"
},
"globals": ["page", "browser", "jestPuppeteer"]
"globals": []
},
"css": {
"linter": {
Expand Down
31 changes: 27 additions & 4 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,40 @@ See the [code style](code_style.md#ui) section for more details.
### Running the Jest front-end tests

The unit tests for the UI are run with [Jest].
The tests are written with react testing library. For the integration tests PollyJS is used to mock APIs.
The tests are written with react testing library.

Integration tests are useful when testing higher level components that would be hard to setup with fetch mock.
They use PollyJS because it helps to automatically record and replay requests/responses.
To refresh the PollyJS recordings (usually when an endpoint response changes), just delete the recordings folder and run `pnpm test:integration` again like described below.
### Running the Playwright integration tests

Integration tests are useful when testing higher level components that would be hard to set up with fetch mock.
They are run with [Playwright] (see `playwright.config.js`) in Firefox, which starts the dev server

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a small note somewhere in these docs to specify that the firefox being used is a custom built one from playwright?

automatically if it isn't already running on port 5000. API responses for the graphs view tests are replayed
from the HAR recordings in `tests/ui/integration/recordings/`; requests not present in a recording fall
through to the dev server proxy.

The integration tests also run in CI (the `javascript-integration-tests` CircleCI job), with two retries
for any test that fails and traces/screenshots uploaded as build artifacts on failure.

To run the tests:

- If you haven't already done so, install local dependencies by running `pnpm install` from the project root.
- Install the Playwright browser once with `npx playwright install firefox`.
- For unit tests run `pnpm test` to execute the tests.
- For integration tests run `pnpm test:integration` to execute the tests.

#### Firefox notes

The integration tests run against Firefox by default. A couple of things are worth knowing
about clipboard access under Firefox:

- Granting clipboard permissions via `context.grantPermissions()` is a Chromium-only Playwright
API and throws on Firefox, so the logviewer copy test only requests those permissions when
`browserName === 'chromium'`.
- Copy/paste would not normally work in a stock headless Firefox build. Playwright ships its own
patched build of Firefox that permits clipboard writes in tests without an explicit grant, so
under Playwright's Firefox the copy test still works seamlessly. This is a non-issue in
practice, just a distinction worth knowing if you ever see clipboard behavior differ outside
of Playwright's bundled browser.

While working on the frontend, you may wish to watch JavaScript files and re-run the unit tests
automatically when files change. To do this, you may run one of the following commands:

Expand Down Expand Up @@ -114,3 +136,4 @@ There are a lot of taskid, revisions, and expected fields to update in tests. F

[biome]: https://biomejs.dev
[prettier]: https://prettier.io
[playwright]: https://playwright.dev
11 changes: 0 additions & 11 deletions jest-puppeteer.config.js

This file was deleted.

6 changes: 0 additions & 6 deletions jest.integration.config.js

This file was deleted.

12 changes: 2 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@
"@babel/preset-env": "7.26.9",
"@babel/preset-react": "7.27.1",
"@biomejs/biome": "2.3.15",
"@pollyjs/adapter-fetch": "6.0.7",
"@pollyjs/adapter-node-http": "6.0.6",
"@pollyjs/adapter-puppeteer": "6.0.6",
"@pollyjs/core": "6.0.6",
"@pollyjs/persister-fs": "6.0.6",
"@playwright/test": "1.62.0",
"@rspack/cli": "1.6.8",
"@rspack/core": "1.6.8",
"@rspack/plugin-react-refresh": "1.5.3",
Expand All @@ -86,13 +82,9 @@
"html-loader": "5.1.0",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jest-environment-puppeteer": "11.0.0",
"jest-puppeteer": "11.0.0",
"markdownlint-cli": "0.43.0",
"puppeteer": "24.2.1",
"sass": "1.101.7",
"sass-loader": "16.0.8",
"setup-polly-jest": "0.11.0",
"style-loader": "4.0.0",
"webpack-merge": "6.0.1"
},
Expand All @@ -112,7 +104,7 @@
"test": "jest --maxWorkers=50%",
"test:coverage": "jest --maxWorkers=50% --coverage",
"test:ci": "jest --maxWorkers=4 --coverage",
"test:integration": "jest --config jest.integration.config.js",
"test:integration": "playwright test",
"test:watch": "jest --watch --maxWorkers=25%"
},
"pnpm": {
Expand Down
38 changes: 38 additions & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { defineConfig, devices } = require('@playwright/test');

module.exports = defineConfig({
testDir: './tests/ui/integration',
testMatch: '**/*.spec.js',
timeout: 60_000,
expect: { timeout: 10_000 },
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
reporter: process.env.CI
? [
['list'],
['html', { open: 'never' }],
['junit', { outputFile: 'test-results/junit.xml' }],
]
: 'list',

use: {
baseURL: 'http://localhost:5000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},

projects: [
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
],

webServer: {
command: 'BROWSER=none pnpm start',
port: 5000,
reuseExistingServer: true,
timeout: 120_000,
},
});
Loading