Skip to content

Commit 656a2c8

Browse files
authored
chore(e2e): Setup e2e test for streaming SSR (#9349)
1 parent 373708c commit 656a2c8

32 files changed

+816
-65
lines changed

.github/actions/actionsLib.mjs

+4-4
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ export function projectCopy(redwoodProjectCwd) {
6262
}
6363

6464
/**
65-
* @param {{ baseKeyPrefix: string, distKeyPrefix: string }} options
65+
* @param {{ baseKeyPrefix: string, distKeyPrefix: string, canary: boolean }} options
6666
*/
67-
export async function createCacheKeys({ baseKeyPrefix, distKeyPrefix }) {
67+
export async function createCacheKeys({ baseKeyPrefix, distKeyPrefix, canary }) {
6868
const baseKey = [
6969
baseKeyPrefix,
7070
process.env.RUNNER_OS,
@@ -76,7 +76,7 @@ export async function createCacheKeys({ baseKeyPrefix, distKeyPrefix }) {
7676
baseKey,
7777
'dependencies',
7878
await hashFiles(['yarn.lock', '.yarnrc.yml'].join('\n')),
79-
].join('-')
79+
].join('-') + (canary ? '-canary' : '')
8080

8181
const distKey = [
8282
dependenciesKey,
@@ -91,7 +91,7 @@ export async function createCacheKeys({ baseKeyPrefix, distKeyPrefix }) {
9191
'lerna.json',
9292
'packages',
9393
].join('\n'))
94-
].join('-')
94+
].join('-') + (canary ? '-canary' : '')
9595

9696
return {
9797
baseKey,

.github/actions/set-up-test-project/action.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ inputs:
99
bundler:
1010
description: The bundler to use (vite or webpack)
1111
default: vite
12+
canary:
13+
description: Upgrade the project to canary?
14+
default: "false"
1215

1316
outputs:
1417
test-project-path:

.github/actions/set-up-test-project/setUpTestProject.mjs

+16-3
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@ core.setOutput('test-project-path', TEST_PROJECT_PATH)
2525

2626
const bundler = core.getInput('bundler')
2727

28+
const canary = core.getInput('canary') === 'true'
29+
30+
2831
console.log({
2932
bundler,
33+
canary
3034
})
3135

3236
console.log()
3337

3438
const {
3539
dependenciesKey,
3640
distKey
37-
} = await createCacheKeys({ baseKeyPrefix: 'test-project', distKeyPrefix: bundler })
41+
} = await createCacheKeys({ baseKeyPrefix: 'test-project', distKeyPrefix: bundler, canary })
3842

3943
/**
4044
* @returns {Promise<void>}
@@ -54,17 +58,20 @@ async function main() {
5458
await sharedTasks()
5559
} else {
5660
console.log(`Cache not found for input keys: ${distKey}, ${dependenciesKey}`)
57-
await setUpTestProject()
61+
await setUpTestProject({
62+
canary: true
63+
})
5864
}
5965

6066
await cache.saveCache([TEST_PROJECT_PATH], distKey)
6167
console.log(`Cache saved with key: ${distKey}`)
6268
}
6369

6470
/**
71+
* *@param {{canary: boolean}} options
6572
* @returns {Promise<void>}
6673
*/
67-
async function setUpTestProject() {
74+
async function setUpTestProject({ canary }) {
6875
const TEST_PROJECT_FIXTURE_PATH = path.join(
6976
REDWOOD_FRAMEWORK_PATH,
7077
'__fixtures__',
@@ -83,6 +90,12 @@ async function setUpTestProject() {
8390
await execInProject('yarn install')
8491
console.log()
8592

93+
if (canary) {
94+
console.log(`Upgrading project to canary`)
95+
await execInProject('yarn rw upgrade -t canary')
96+
console.log()
97+
}
98+
8699
await cache.saveCache([TEST_PROJECT_PATH], dependenciesKey)
87100
console.log(`Cache saved with key: ${dependenciesKey}`)
88101

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: Streaming-SSR Related Changes
2+
description: Determines if the PR makes any changes related to SSR or streaming
3+
outputs:
4+
rsc-related-changes:
5+
description: If the PR makes any SSR related changes
6+
runs:
7+
using: node20
8+
main: ssr_related_changes.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "ssr_related_changes",
3+
"private": true,
4+
"dependencies": {
5+
"@actions/core": "1.10.0",
6+
"@actions/exec": "1.1.1"
7+
},
8+
"packageManager": "yarn@3.6.3"
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import core from '@actions/core'
2+
import { exec, getExecOutput } from '@actions/exec'
3+
4+
async function main() {
5+
const branch = process.env.GITHUB_BASE_REF
6+
7+
// If there is no branch, we're not in a pull request
8+
if (!branch) {
9+
core.setOutput('ssr-related-changes', false)
10+
return
11+
}
12+
13+
await exec(`git fetch origin ${branch}`)
14+
15+
const { stdout } = await getExecOutput(
16+
`git diff origin/${branch} --name-only`
17+
)
18+
19+
const changedFiles = stdout.toString().trim().split('\n').filter(Boolean)
20+
21+
for (const changedFile of changedFiles) {
22+
console.log('changedFile', changedFile)
23+
24+
if (
25+
changedFile.startsWith('tasks/smoke-tests/streaming-ssr') ||
26+
changedFile.startsWith('tasks/smoke-tests/basePlaywright.config.ts') ||
27+
changedFile.startsWith('github/actions/ssr_related_changes/') ||
28+
changedFile.startsWith('packages/internal/') ||
29+
changedFile.startsWith('packages/project-config/') ||
30+
changedFile.startsWith('packages/web/') ||
31+
changedFile.startsWith('packages/router/') ||
32+
changedFile.startsWith('packages/web-server/') ||
33+
changedFile.startsWith('packages/vite/')
34+
) {
35+
core.setOutput('ssr-related-changes', true)
36+
return
37+
}
38+
}
39+
40+
core.setOutput('ssr-related-changes', false)
41+
}
42+
43+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# This file is generated by running "yarn install" inside your project.
2+
# Manual changes might be lost - proceed with caution!
3+
4+
__metadata:
5+
version: 6
6+
cacheKey: 8c0
7+
8+
"@actions/core@npm:1.10.0":
9+
version: 1.10.0
10+
resolution: "@actions/core@npm:1.10.0"
11+
dependencies:
12+
"@actions/http-client": ^2.0.1
13+
uuid: ^8.3.2
14+
checksum: 9214d1e0cf5cf2a5d48b8f3b12488c6be9f6722ea60f2397409226e8410b5a3e12e558d9b66c93469d180399865ec20180119408a1770f026bd9ecac6965fcda
15+
languageName: node
16+
linkType: hard
17+
18+
"@actions/exec@npm:1.1.1":
19+
version: 1.1.1
20+
resolution: "@actions/exec@npm:1.1.1"
21+
dependencies:
22+
"@actions/io": ^1.0.1
23+
checksum: 4a09f6bdbe50ce68b5cf8a7254d176230d6a74bccf6ecc3857feee209a8c950ba9adec87cc5ecceb04110182d1c17117234e45557d72fde6229b7fd3a395322a
24+
languageName: node
25+
linkType: hard
26+
27+
"@actions/http-client@npm:^2.0.1":
28+
version: 2.0.1
29+
resolution: "@actions/http-client@npm:2.0.1"
30+
dependencies:
31+
tunnel: ^0.0.6
32+
checksum: b58987ba2f53d7988f612ede7ff834573a3360c21f8fdea9fea92f26ada0fd0efafb22aa7d83f49c18965a5b765775d5253e2edb8d9476d924c4b304ef726b67
33+
languageName: node
34+
linkType: hard
35+
36+
"@actions/io@npm:^1.0.1":
37+
version: 1.1.2
38+
resolution: "@actions/io@npm:1.1.2"
39+
checksum: 61c871bbee1cf58f57917d9bb2cf6bb7ea4dc40de3f65c7fb4ec619ceff57fc98f56be9cca2d476b09e7a96e1cba0d88cd125c4f690d384b9483935186f256c1
40+
languageName: node
41+
linkType: hard
42+
43+
"ssr_related_changes@workspace:.":
44+
version: 0.0.0-use.local
45+
resolution: "ssr_related_changes@workspace:."
46+
dependencies:
47+
"@actions/core": 1.10.0
48+
"@actions/exec": 1.1.1
49+
languageName: unknown
50+
linkType: soft
51+
52+
"tunnel@npm:^0.0.6":
53+
version: 0.0.6
54+
resolution: "tunnel@npm:0.0.6"
55+
checksum: e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75
56+
languageName: node
57+
linkType: hard
58+
59+
"uuid@npm:^8.3.2":
60+
version: 8.3.2
61+
resolution: "uuid@npm:8.3.2"
62+
bin:
63+
uuid: dist/bin/uuid
64+
checksum: bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54
65+
languageName: node
66+
linkType: hard

.github/workflows/ci.yml

+99
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,31 @@ jobs:
6464
id: rsc-related-changes
6565
uses: ./.github/actions/rsc_related_changes
6666

67+
ssr-related-changes:
68+
needs: check
69+
if: github.repository == 'redwoodjs/redwood'
70+
name: 🌤️ SSR related changes?
71+
runs-on: ubuntu-latest
72+
outputs:
73+
ssr-related-changes: ${{ steps.ssr-related-changes.outputs.ssr-related-changes }}
74+
steps:
75+
- uses: actions/checkout@v3
76+
77+
- name: ⬢ Set up Node.js
78+
uses: actions/setup-node@v3
79+
with:
80+
node-version: 18
81+
82+
- name: 🐈 Yarn install
83+
working-directory: ./.github/actions/ssr_related_changes
84+
run: yarn install --inline-builds
85+
env:
86+
GITHUB_TOKEN: ${{ github.token }}
87+
88+
- name: 🌤️ SSR related changes?
89+
id: ssr-related-changes
90+
uses: ./.github/actions/ssr_related_changes
91+
6792
check:
6893
needs: only-doc-changes
6994
if: needs.only-doc-changes.outputs.only-doc-changes == 'false'
@@ -232,6 +257,80 @@ jobs:
232257
steps:
233258
- run: echo "Only doc changes"
234259

260+
ssr-smoke-tests:
261+
needs: ssr-related-changes
262+
if: needs.ssr-related-changes.outputs.ssr-related-changes == 'true'
263+
264+
strategy:
265+
matrix:
266+
os: [ubuntu-latest]
267+
# [ubuntu-latest, windows-latest] disabled, because windows misbehaving
268+
# waiting for help from main-man Josh
269+
270+
name: 🔁 SSR Smoke tests / ${{ matrix.os }}
271+
runs-on: ${{ matrix.os }}
272+
273+
env:
274+
REDWOOD_CI: 1
275+
REDWOOD_VERBOSE_TELEMETRY: 1
276+
277+
steps:
278+
- uses: actions/checkout@v3
279+
280+
- name: ⬢ Set up Node.js
281+
uses: actions/setup-node@v3
282+
with:
283+
node-version: 18
284+
285+
- name: 🐈 Set up yarn cache
286+
uses: ./.github/actions/set-up-yarn-cache
287+
288+
- name: 🐈 Yarn install
289+
run: yarn install --inline-builds
290+
env:
291+
GITHUB_TOKEN: ${{ github.token }}
292+
293+
- name: 🔨 Build
294+
run: yarn build
295+
296+
- name: 🌲 Set up test project
297+
id: set-up-test-project
298+
uses: ./.github/actions/set-up-test-project
299+
with:
300+
bundler: vite
301+
canary: true
302+
env:
303+
REDWOOD_DISABLE_TELEMETRY: 1
304+
YARN_ENABLE_IMMUTABLE_INSTALLS: false
305+
306+
- name: Run SSR codemods on test project
307+
run: ./tasks/test-project/convert-to-ssr-fixture ${{ steps.set-up-test-project.outputs.test-project-path }}
308+
env:
309+
REDWOOD_DISABLE_TELEMETRY: 1
310+
311+
- name: 🎭 Install playwright dependencies
312+
run: npx playwright install --with-deps chromium
313+
314+
- name: Run SSR [DEV] smoke tests
315+
working-directory: ./tasks/smoke-tests/streaming-ssr-dev
316+
run: npx playwright test
317+
env:
318+
REDWOOD_TEST_PROJECT_PATH: '${{ steps.set-up-test-project.outputs.test-project-path }}'
319+
REDWOOD_DISABLE_TELEMETRY: 1
320+
321+
- name: Build for production
322+
working-directory: ${{ steps.set-up-test-project.outputs.test-project-path }}
323+
run: yarn rw build --no-prerender
324+
env:
325+
REDWOOD_DISABLE_TELEMETRY: 1
326+
327+
- name: Run SSR [PROD] smoke tests
328+
working-directory: ./tasks/smoke-tests/streaming-ssr-prod
329+
run: npx playwright test
330+
env:
331+
REDWOOD_TEST_PROJECT_PATH: '${{ steps.set-up-test-project.outputs.test-project-path }}'
332+
REDWOOD_DISABLE_TELEMETRY: 1
333+
235334
smoke-tests:
236335
needs: check
237336

.yarnrc.yml

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ plugins:
1717
preferInteractive: true
1818

1919
yarnPath: .yarn/releases/yarn-3.6.3.cjs
20+

packages/cli/src/commands/experimental/setupStreamingSsrHandler.js

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'path'
33

44
import { Listr } from 'listr2'
55

6+
import { addWebPackages } from '@redwoodjs/cli-helpers'
67
import { getConfigPath } from '@redwoodjs/project-config'
78
import { errorTelemetry } from '@redwoodjs/telemetry'
89

@@ -158,6 +159,9 @@ export const handler = async ({ force, verbose }) => {
158159
})
159160
},
160161
},
162+
addWebPackages([
163+
'@apollo/experimental-nextjs-app-support@0.0.0-commit-b8a73fe',
164+
]),
161165
{
162166
task: () => {
163167
printTaskEpilogue(command, description, EXPERIMENTAL_TOPIC_ID)

packages/vite/src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { getConfig, getPaths } from '@redwoodjs/project-config'
1010

1111
import handleJsAsJsx from './plugins/vite-plugin-jsx-loader'
1212
import removeFromBundle from './plugins/vite-plugin-remove-from-bundle'
13+
import swapApolloProvider from './plugins/vite-plugin-swap-apollo-provider'
1314

1415
/**
1516
* Pre-configured vite plugin, with required config for Redwood apps.
@@ -261,6 +262,8 @@ export default function redwoodPluginVite(): PluginOption[] {
261262
}
262263
},
263264
},
265+
// We can remove when streaming is stable
266+
rwConfig.experimental.streamingSsr.enabled && swapApolloProvider(),
264267
// -----------------
265268
handleJsAsJsx(),
266269
// Remove the splash-page from the bundle.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import assert from 'node:assert/strict'
2+
import { describe, it } from 'node:test'
3+
4+
import plugin from '../vite-plugin-swap-apollo-provider.js'
5+
6+
// @ts-expect-error node test not configured correctly
7+
const swapApolloProvider = plugin.default
8+
9+
10+
describe('excludeModule', () => {
11+
it('should swap the import', async() => {
12+
const plugin = swapApolloProvider()
13+
14+
const output = await plugin.transform(`import ApolloProvider from '@redwoodjs/web/apollo'`, '/Users/dac09/Experiments/ssr-2354/web/src/App.tsx')
15+
16+
assert.strictEqual(output, "import ApolloProvider from '@redwoodjs/web/dist/apollo/suspense'")
17+
})
18+
})

0 commit comments

Comments
 (0)