Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
9 changes: 9 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ jobs:
# branch protection settings for `next`.
base-path: [false]
react-compiler: [false]
cache-components: [false]
next-version:
# Only keep versions where there were relevant changes in the app router core,
# and the previous one to use as a baseline.
Expand All @@ -178,6 +179,9 @@ jobs:
- next-version: "latest"
base-path: "/base"
react-compiler: true
- next-version: "latest"
cache-components: true
react-compiler: true
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
Expand All @@ -190,11 +194,16 @@ jobs:
- name: Install Next.js version ${{ matrix.next-version }}
if: ${{ matrix.next-version != 'local' }}
run: pnpm add --filter e2e-next next@${{ matrix.next-version }}
- name: Run cacheComponents codemod
if: ${{ matrix.cache-components }}
run: pnpm run cacheComponents:codemod
working-directory: packages/e2e/next
- name: Run integration tests
run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter e2e-next
env:
BASE_PATH: ${{ matrix.base-path && matrix.base-path || '/' }}
REACT_COMPILER: ${{ matrix.react-compiler }}
CACHE_COMPONENTS: ${{ matrix.cache-components }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
Expand Down
13 changes: 11 additions & 2 deletions packages/e2e/next/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
const basePath =
process.env.BASE_PATH === '/' ? undefined : process.env.BASE_PATH

const enableCacheComponents =
process.env.CACHE_COMPONENTS === 'true'
? {
cacheComponents: true
}
: {}

/** @type {import('next').NextConfig } */
const config = {
basePath,
productionBrowserSourceMaps: true,
...enableCacheComponents,
reactCompiler: process.env.REACT_COMPILER === 'true',
experimental: {
clientRouterFilter: false,
Expand All @@ -27,8 +35,9 @@ const config = {
}

console.info(`Next.js config:
basePath: ${config.basePath}
reactCompiler: ${config.reactCompiler}
basePath: ${config.basePath}
reactCompiler: ${config.reactCompiler}
cacheComponents: ${config.cacheComponents}
`)

export default config
3 changes: 2 additions & 1 deletion packages/e2e/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"build": "next build",
"start": "NODE_OPTIONS='--enable-source-maps=true' next start --port 3001",
"pretest": "playwright install chromium",
"test": "playwright test --project=chromium"
"test": "playwright test --project=chromium",
"cacheComponents:codemod": "node scripts/cache-components-codemod.ts"
},
"dependencies": {
"next": "catalog:next",
Expand Down
60 changes: 60 additions & 0 deletions packages/e2e/next/scripts/cache-components-codemod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { exec } from 'node:child_process'
import { resolve } from 'node:path'

function grepFilesWithDynamicExport(dir: string): Promise<string[]> {
return new Promise((resolve, reject) => {
exec(
`grep -rl "export const dynamic = " ${dir}`,
(error, stdout, stderr) => {
if (error) {
reject(new Error(`Error executing grep: ${error.message}`))
return
}
if (stderr) {
reject(new Error(`Grep stderr: ${stderr}`))
return
}

const files = stdout.split('\n').filter(Boolean)
resolve(files)
}
)
})
}

function commentDynamicExportInFile(filePath: string) {
return new Promise<void>((resolve, reject) => {
exec(
`sed -i '' 's/export const dynamic = /\\/\\/ export const dynamic = /' "${filePath}"`,
(error, _stdout, stderr) => {
if (error) {
reject(
new Error(`Error commenting line in ${filePath}: ${error.message}`)
)
return
}
if (stderr) {
reject(new Error(`sed error for ${filePath}: ${stderr}`))
return
}
console.info(`Commented dynamic export in: ${filePath}`)
resolve()
}
)
})
}

async function main() {
try {
const sourceDir = resolve(import.meta.dirname, '../src')
const files = await grepFilesWithDynamicExport(sourceDir)
console.table(files)
for (const file of files) {
await commentDynamicExportInFile(file)
}
} catch (error) {
console.error(error)
}
}

main()
8 changes: 4 additions & 4 deletions packages/e2e/next/specs/persist-across-navigation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ test('Persists search params across navigation using a generated Link href', asy
page
}) => {
await navigateTo(page, '/app/persist-across-navigation/a')
await page.locator('input[type=text]').fill('foo')
await page.locator('input[type=checkbox]').check()
await page.getByRole('textbox').fill('foo')
await page.getByRole('checkbox').check()
await page.locator('a').click()
await expect(page).toHaveURL(/\/app\/persist-across-navigation\/b/)
await expect(page).toHaveURL(url => url.search === '?q=foo&checked=true')
await expect(page.locator('input[type=text]')).toHaveValue('foo')
await expect(page.locator('input[type=checkbox]')).toBeChecked()
await expect(page.getByRole('textbox')).toHaveValue('foo')
await expect(page.getByRole('checkbox')).toBeChecked()
})
16 changes: 10 additions & 6 deletions packages/e2e/next/specs/repros.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,18 @@ test('Reproduction for issue #498', async ({ page }) => {

test('Reproduction for issue #542', async ({ page }) => {
await navigateTo(page, '/app/repro-542/a', '?q=foo&r=bar')
await expect(page.locator('#q')).toHaveText('foo')
await expect(page.locator('#r')).toHaveText('bar')
await expect(page.locator('#initial')).toHaveText('{"q":"foo","r":"bar"}')
await expect(page.locator('#q').first()).toHaveText('foo')
await expect(page.locator('#r').first()).toHaveText('bar')
await expect(page.locator('#initial').first()).toHaveText(
'{"q":"foo","r":"bar"}'
)
await page.locator('a').click()
await expect(page).toHaveURL(url => url.search === '')
await expect(page.locator('#q')).toHaveText('')
await expect(page.locator('#r')).toHaveText('')
await expect(page.locator('#initial')).toHaveText('{"q":null,"r":null}')
await expect(page.locator('#q').first()).toHaveText('')
await expect(page.locator('#r').first()).toHaveText('')
await expect(page.locator('#initial').first()).toHaveText(
'{"q":null,"r":null}'
)
})

test.describe('Reproduction for issue #630', () => {
Expand Down
Loading
Loading