Skip to content

Commit d1cbc72

Browse files
ascorbicpieh
andauthored
ci: run tests against different versions (#314)
* ci: run tests against different versions * ci: ignore lockfiles for pnpm in fixtures * chore: allow manual trigger * chore: install next version in e2e * chore: log install command * chore: use matrix for unit and integration tests * chore: patch package.jsons * chore: add fixture dep * chore: handle errors in patching * chore: allow fixtures and tests to exclude versions * chore: update output syntax * chore: check version in integration tests too * chore: update actions * chore: handle errors reading package.json * chore: don't patch inside node_modules * chore: add doc * chore: allow setting site id * chore: fix pnpm test * chore: artifact name * chore: make stream test conditional * chore: format with prettier * chore: fixes and logging for prepare script * chore: shard e2e tests * chore: merge reports * chore: correct reporter * chore: handle more version constraints * test: hacky mocking for request-context leak test to work with dynamic import and require * test: provide NEXT_VERSION env var also to vitest execution step so smoke tests update next versions as well * test: don't rely on pnpm-lock.yaml to decide on package-manager * test: handle packageManager field not being set * test: drop commented out debug code * revert pnpm-lock.yaml changes * test: allow updating pnpm lock in vitest fixtures * test: use --force on vitest tests with pnpm * test: revert changing integration fixture pnpm command * test: use actual resolved next version to calculate fixture cache key * test: don't revert version, otherwise pnpm lock won't match and if you run against non default NEXT_VERSION some mess in working dir seems acceptable to make things work * test: mock requests instead of spinning actual http server because 13.5.1 doesn't seem to allow overwriting env vars on execution, so we can't change fetch target dynamically * don't install repo dependencies via pnpm, we use npm for that * chore: format with prettier * actually don't use custom pnpm action at all, we are updating dependencies so pnpm locks are not to be trusted for caching * separate playwright reports for each next version * fix blob report path ? --------- Co-authored-by: ascorbic <[email protected]> Co-authored-by: Michal Piechowiak <[email protected]> Co-authored-by: pieh <[email protected]>
1 parent 2ca5313 commit d1cbc72

Some content is hidden

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

64 files changed

+967
-17488
lines changed

.github/actions/pnpm/action.yaml

-26
This file was deleted.

.github/workflows/run-tests.yml

+104-14
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,53 @@ name: 'Run tests'
22
on:
33
pull_request:
44
branches: [main]
5+
schedule:
6+
- cron: '0 6 * * *' # Run every day at 6am UTC
7+
workflow_dispatch:
8+
inputs:
9+
versions:
10+
description: 'The versions of Next.js to test against (quoted and comma separated)'
11+
required: false
12+
default: 'latest'
513

614
jobs:
15+
setup:
16+
runs-on: ubuntu-latest
17+
outputs:
18+
matrix: ${{ steps.set-matrix.outputs.matrix }}
19+
steps:
20+
- name: Check PR labels
21+
if: github.event_name == 'pull_request'
22+
id: check-labels
23+
uses: actions/github-script@v7
24+
with:
25+
script: |
26+
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
27+
owner: context.repo.owner,
28+
repo: context.repo.repo,
29+
issue_number: context.payload.pull_request.number,
30+
});
31+
return labels.some(label => label.name === 'autorelease: pending' || label.name === 'test all versions');
32+
- name: Set Next.js versions to test
33+
id: set-matrix
34+
# If this is the nightly build or a release PR then run the full matrix of versions
35+
run: |
36+
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
37+
echo "matrix=${{ github.event.inputs.versions }}" >> $GITHUB_OUTPUT
38+
elif [ "${{ github.event_name }}" = "schedule" ] || [ "${{ steps.check-labels.outputs.result }}" = "true" ]; then
39+
echo "matrix=[\"latest\", \"canary\", \"13.5.1\"]" >> $GITHUB_OUTPUT
40+
else
41+
echo "matrix=[\"latest\"]" >> $GITHUB_OUTPUT
42+
fi
743
e2e:
44+
needs: setup
845
runs-on: ubuntu-latest
46+
strategy:
47+
fail-fast: false
48+
matrix:
49+
version: ${{ fromJson(needs.setup.outputs.matrix) }}
50+
shard: [1, 2, 3, 4]
51+
952
steps:
1053
- uses: actions/checkout@v4
1154
- name: 'Install Node'
@@ -15,8 +58,9 @@ jobs:
1558
cache: 'npm'
1659
cache-dependency-path: '**/package-lock.json'
1760
- uses: oven-sh/setup-bun@v1
18-
- name: Setup PNPM
19-
uses: ./.github/actions/pnpm
61+
- name: setup pnpm/yarn
62+
run: corepack enable
63+
shell: bash
2064
- name: Install Deno
2165
uses: denoland/setup-deno@v1
2266
with:
@@ -33,7 +77,7 @@ jobs:
3377
- name: Get installed Playwright version
3478
id: playwright-version
3579
run: echo "::set-output name=version::$(npm view @playwright/test version)"
36-
- uses: actions/cache@v3
80+
- uses: actions/cache@v4
3781
id: playwright-cache
3882
with:
3983
path: '~/.cache/ms-playwright'
@@ -44,23 +88,27 @@ jobs:
4488
if: steps.playwright-cache.outputs.cache-hit != 'true'
4589
run: npx playwright install --with-deps
4690
- name: Run Playwright tests
47-
run: npm run e2e:ci
91+
run: npm run e2e:ci -- --shard=${{ matrix.shard }}/4
4892
env:
4993
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TOKEN }}
50-
- uses: actions/upload-artifact@v3
94+
NEXT_VERSION: ${{ matrix.version }}
95+
- name: Upload blob report to GitHub Actions Artifacts
96+
uses: actions/upload-artifact@v4
5197
if: always()
5298
with:
53-
name: playwright-report
54-
path: playwright-report/
55-
retention-days: 30
99+
name: blob-report-${{matrix.version}}-${{ matrix.shard }}
100+
path: blob-report
101+
retention-days: 1
56102

57103
test:
104+
needs: setup
58105
runs-on: ${{ matrix.os }}
59106
strategy:
60107
fail-fast: false
61108
matrix:
62-
shard: [1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8]
109+
shard: [1, 2, 3, 4, 5, 6, 7, 8]
63110
os: [ubuntu-latest, windows-latest]
111+
version: ${{ fromJson(needs.setup.outputs.matrix) }}
64112
steps:
65113
- uses: actions/checkout@v4
66114
- name: 'Install Node'
@@ -69,8 +117,9 @@ jobs:
69117
node-version: '18.x'
70118
cache: 'npm'
71119
cache-dependency-path: '**/package-lock.json'
72-
- name: Setup PNPM
73-
uses: ./.github/actions/pnpm
120+
- name: setup pnpm/yarn
121+
run: corepack enable
122+
shell: bash
74123
- name: Install Deno
75124
uses: denoland/setup-deno@v1
76125
with:
@@ -86,6 +135,9 @@ jobs:
86135
run: |
87136
npm i -g netlify-cli
88137
netlify login
138+
- name: Get actual Next.js version
139+
id: actual-next-version
140+
run: echo "version=$(npm view next@${{ matrix.version }} version)" >> $GITHUB_OUTPUT
89141
- name: Compute Fixtures Cache Key
90142
id: fixture-cache-key
91143
# Fixtures only need to be rebuilt if anything in the tests/fixtures directory changes,
@@ -99,12 +151,50 @@ jobs:
99151
uses: actions/cache@v4
100152
with:
101153
path: tests/fixtures
102-
key: integration-fixtures-${{ runner.os }}-${{ steps.fixture-cache-key.outputs.key }}
154+
key:
155+
integration-fixtures-${{ runner.os }}-${{steps.next-version.outputs.version}}-${{
156+
steps.fixture-cache-key.outputs.key }}
103157
- name: 'Prepare Fixtures'
104158
if: steps.cache-fixtures.outputs.cache-hit != 'true'
105159
run: npm run pretest
160+
env:
161+
NEXT_VERSION: ${{ matrix.version }}
106162
- name: 'Test'
107-
run: npm run test:ci -- --shard=${{ matrix.shard }}
163+
run: npm run test:ci -- --shard=${{ matrix.shard }}/8
108164
env:
109165
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TOKEN }}
110-
TEMP: ${{ github.workspace }}/..
166+
NEXT_VERSION: ${{ matrix.version }}
167+
TEMP: ${{ github.workspace }}/..
168+
merge-reports:
169+
if: always()
170+
needs: [setup,e2e]
171+
strategy:
172+
fail-fast: false
173+
matrix:
174+
version: ${{ fromJson(needs.setup.outputs.matrix) }}
175+
176+
runs-on: ubuntu-latest
177+
steps:
178+
- uses: actions/checkout@v4
179+
- uses: actions/setup-node@v4
180+
with:
181+
node-version: 18
182+
- name: Install dependencies
183+
run: npm ci
184+
185+
- name: Download blob reports from GitHub Actions Artifacts
186+
uses: actions/download-artifact@v4
187+
with:
188+
path: all-blob-reports
189+
pattern: blob-report-${{ matrix.version }}-*
190+
merge-multiple: true
191+
192+
- name: Merge into HTML Report
193+
run: npx playwright merge-reports --reporter html ./all-blob-reports
194+
195+
- name: Upload HTML report
196+
uses: actions/upload-artifact@v4
197+
with:
198+
name: html-report-${{ matrix.version }}-attempt-${{ github.run_attempt }}
199+
path: playwright-report
200+
retention-days: 14

.github/workflows/test-e2e.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
run: echo "PATH=$(pnpm store path --silent)" >> ${GITHUB_OUTPUT}
7575

7676
- name: cache pnpm deps
77-
uses: actions/cache@v3
77+
uses: actions/cache@v4
7878
with:
7979
path: ${{ steps.pnpm-store.outputs.PATH }}
8080
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -86,7 +86,7 @@ jobs:
8686
run: echo "PATH=$(npm config get cache)" >> ${GITHUB_OUTPUT}
8787

8888
- name: cache npm deps
89-
uses: actions/cache@v3
89+
uses: actions/cache@v4
9090
with:
9191
path: ${{ steps.npm-cache.outputs.PATH }}
9292
key: node-cache-${{ hashFiles('**/package-lock.json') }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ deno.lock
1414
.eslintcache
1515
/report/index.html
1616
.DS_Store
17+
tests/fixtures/**/package-lock.json

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ deno.lock
1010
tests/fixtures/simple-next-app-dist-dir/cool/output
1111
.nx
1212
custom-dist-dir
13+
pnpm.lock
1314
# to avoid needing extra permissions to format files
1415
.github/workflows

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ For a simple next.js app
2828

2929
## Testing
3030

31+
The repo includes two types of tests: e2e tests in the repo that use Playwright, integration tests
32+
that use Vitest.
33+
34+
By default the e2e and integration tests run against the latest version of Next.js. To run tests
35+
against a specific version, set the `NEXT_VERSION` environment variable to the desired version.
36+
37+
By default, PRs will run the integration tests against the latest version of Next.js. To run tests
38+
against `latest`, `canary` and `13.5.1`, apply the `test all versions` label to the PR when you
39+
create it. These also run nightly and on release PRs.
40+
3141
### Integration testing
3242

3343
How to add new integration test scenarios to the application:
@@ -75,6 +85,12 @@ following:
7585
> [!TIP] If you'd like to always keep the deployment and the local fixture around for
7686
> troubleshooting, run `E2E_PERSIST=1 npm run e2e`.
7787
88+
### Next.js tests
89+
90+
There is a script `run-local-test.sh` and GitHub workflow that runs the e2e tests from the Next.js
91+
repo against this repo. It requires that `next.js` is checked out in the same parent directory as
92+
this repo, and is run from this repo with `./run-local-test.sh your-test-pattern-here`.
93+
7894
#### cleanup old deploys
7995

8096
To cleanup old and dangling deploys from failed builds you can run the following script:

package-lock.json

+66-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"picomatch": "^3.0.1",
8383
"prettier": "^3.2.5",
8484
"regexp-tree": "^0.1.27",
85+
"semver": "^7.6.0",
8586
"typescript": "^5.1.6",
8687
"unionfs": "^4.5.1",
8788
"uuid": "^9.0.1",

playwright.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default defineConfig({
1515
workers: process.env.CI ? 3 : undefined,
1616
globalSetup: './tests/test-setup-e2e.ts',
1717
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
18-
reporter: 'html',
18+
reporter: process.env.CI ? 'blob' : 'list',
1919
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
2020
use: {
2121
/* Base URL to use in actions like `await page.goto('/')`. */

0 commit comments

Comments
 (0)