JJ Kasper 2023-04-03 13:37:14 -07:00 committed by GitHub
parent 036f540bb4
commit 320ebe2d34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 347 additions and 255 deletions

View file

@ -655,7 +655,7 @@ jobs:
name: next-swc-test-binary
path: packages/next-swc/native
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && npm i -g pnpm@${PNPM_VERSION} > /dev/null && NEXT_TEST_JOB=1 NEXT_TEST_CNA=1 xvfb-run node run-tests.js test/integration/create-next-app/index.test.ts test/integration/create-next-app/templates.test.ts >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && npm i -g pnpm@${PNPM_VERSION} > /dev/null && NEXT_TEST_JOB=1 NEXT_TEST_CNA=1 xvfb-run node run-tests.js test/integration/create-next-app/index.test.ts test/integration/create-next-app/templates.test.ts >> /proc/1/fd/1"
if: ${{ needs.build.outputs.docsChange == 'nope' }}
- name: Upload test trace
@ -693,7 +693,7 @@ jobs:
key: ${{ github.sha }}-${{ github.run_number }}
- name: Run tests
run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && npm i -g pnpm@${PNPM_VERSION} > /dev/null && cd ./packages/next-codemod && pnpm build && pnpm test >> /proc/1/fd/1"
run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && npm i -g pnpm@${PNPM_VERSION} > /dev/null && cd ./packages/next-codemod && pnpm build && pnpm test >> /proc/1/fd/1"
testIntegration:
name: Test Integration
@ -758,7 +758,7 @@ jobs:
name: next-swc-test-binary
path: packages/next-swc/native
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && npm i -g pnpm@${PNPM_VERSION} > /dev/null && NEXT_TEST_JOB=1 TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/28 >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && npm i -g pnpm@${PNPM_VERSION} > /dev/null && NEXT_TEST_JOB=1 TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/28 >> /proc/1/fd/1"
if: ${{needs.build.outputs.docsChange == 'nope'}}
- name: Upload test trace
@ -855,7 +855,7 @@ jobs:
name: next-swc-test-binary
path: packages/next-swc/native
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && node -v && npm i -g pnpm@${PNPM_VERSION} > /dev/null && __INTERNAL_NEXT_DEV_TEST_TURBO_DEV=TRUE __INTERNAL_CUSTOM_TURBOPACK_BINDINGS=${NEXT_BINDINGS_BIN} __INTERNAL_NEXT_DEV_TEST_TURBO_GLOB_MATCH=${NEXT_DEV_TEST_GLOB} NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_JOB=1 NEXT_TEST_MODE=dev TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js --type development --timings -c 1 $TEST_FILES_LIST >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && node -v && npm i -g pnpm@${PNPM_VERSION} > /dev/null && __INTERNAL_NEXT_DEV_TEST_TURBO_DEV=TRUE __INTERNAL_CUSTOM_TURBOPACK_BINDINGS=${NEXT_BINDINGS_BIN} __INTERNAL_NEXT_DEV_TEST_TURBO_GLOB_MATCH=${NEXT_DEV_TEST_GLOB} NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_JOB=1 NEXT_TEST_MODE=dev TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js --type development --timings -c 1 $TEST_FILES_LIST >> /proc/1/fd/1"
name: Run test/development
if: ${{needs.build.outputs.docsChange == 'nope'}}
@ -901,7 +901,7 @@ jobs:
name: next-swc-test-binary
path: packages/next-swc/native
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_MAINTENANCE_VERSION }} | FORCE=1 bash && npm i -g pnpm@${PNPM_VERSION} > /dev/null && BROWSERNAME=firefox NEXT_TEST_JOB=1 TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js test/integration/production/test/index.test.js >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_MAINTENANCE_VERSION }} ./scripts/setup-node.sh && npm i -g pnpm@${PNPM_VERSION} > /dev/null && BROWSERNAME=firefox NEXT_TEST_JOB=1 TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js test/integration/production/test/index.test.js >> /proc/1/fd/1"
if: ${{needs.build.outputs.docsChange == 'nope'}}
testSafari:
@ -955,7 +955,7 @@ jobs:
name: next-swc-test-binary
path: packages/next-swc/native
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && node -v && npm i -g pnpm@${PNPM_VERSION} > /dev/null && BROWSER_NAME=firefox NEXT_TEST_JOB=1 TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js test/integration/production/test/index.test.js >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && node -v && npm i -g pnpm@${PNPM_VERSION} > /dev/null && BROWSER_NAME=firefox NEXT_TEST_JOB=1 TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js test/integration/production/test/index.test.js >> /proc/1/fd/1"
if: ${{needs.build.outputs.docsChange == 'nope'}}
publishRelease:
@ -1052,7 +1052,7 @@ jobs:
- run: RESET_VC_PROJECT=true node scripts/reset-vercel-project.mjs
name: Reset test project
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && npm i -g pnpm@${PNPM_VERSION} > /dev/null && VERCEL_TEST_TOKEN=${{ secrets.VERCEL_TEST_TOKEN }} VERCEL_TEST_TEAM=vtest314-next-e2e-tests NEXT_TEST_JOB=1 NEXT_TEST_MODE=deploy TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js --type e2e >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && npm i -g pnpm@${PNPM_VERSION} > /dev/null && VERCEL_TEST_TOKEN=${{ secrets.VERCEL_TEST_TOKEN }} VERCEL_TEST_TEAM=vtest314-next-e2e-tests NEXT_TEST_JOB=1 NEXT_TEST_MODE=deploy TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} xvfb-run node run-tests.js --type e2e >> /proc/1/fd/1"
name: Run test/e2e (deploy)
- name: Upload test trace
@ -1274,7 +1274,7 @@ jobs:
name: next-swc-test-binary
path: packages/next-swc/native
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ env.NODE_LTS_VERSION }} | FORCE=1 bash && node -v && node ./scripts/setup-wasm.mjs && npm i -g pnpm@${PNPM_VERSION} > /dev/null && TEST_WASM=true xvfb-run node run-tests.js test/integration/production/test/index.test.js test/e2e/streaming-ssr/index.test.ts >> /proc/1/fd/1"
- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && node -v && node ./scripts/setup-wasm.mjs && npm i -g pnpm@${PNPM_VERSION} > /dev/null && TEST_WASM=true xvfb-run node run-tests.js test/integration/production/test/index.test.js test/e2e/streaming-ssr/index.test.ts >> /proc/1/fd/1"
if: ${{needs.build.outputs.docsChange == 'nope'}}
# Build binaries for publishing

View file

@ -1247,12 +1247,15 @@ export default async function build(
// each worker will consume ~1GB of memory in a production build.
// For example, if the system has 10 CPU cores and 8GB of remaining memory
// we will use 8 workers.
const numWorkers =
const numWorkers = Math.max(
config.experimental.cpus !== defaultConfig.experimental!.cpus
? config.experimental.cpus
? (config.experimental.cpus as number)
: Math.min(
config.experimental.cpus || 1,
Math.floor(os.freemem() / 1e9)
),
// enforce a minimum of 4 workers
4
)
const staticWorkers = new Worker(staticWorker, {

6
scripts/setup-node.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
# retry setting up Node.js version 5 times waiting 15 seconds between
for i in 1 2 3 4 5;
do curl -s https://install-node.vercel.app/v${NODE_VERSION} | FORCE=1 bash && break || sleep 15;
done

View file

@ -9,6 +9,7 @@ import {
runNextCommand,
runNextCommandDev,
} from 'next-test-utils'
import fs from 'fs-extra'
import { join } from 'path'
import pkg from 'next/package'
import http from 'http'
@ -17,7 +18,191 @@ import stripAnsi from 'strip-ansi'
const dir = join(__dirname, '..')
const dirDuplicateSass = join(__dirname, '../duplicate-sass')
const testExitSignal = async (
killSignal = '',
args = [],
readyRegex = /Creating an optimized production/
) => {
let instance
const killSigint = (inst) => {
instance = inst
}
let output = ''
let cmdPromise = runNextCommand(args, {
ignoreFail: true,
instance: killSigint,
onStdout: (msg) => {
output += stripAnsi(msg)
},
}).catch((err) => expect.fail(err.message))
await check(() => output, readyRegex)
instance.kill(killSignal)
const { code, signal } = await cmdPromise
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitSignal = process.platform === `win32` ? killSignal : null
expect(signal).toBe(expectedExitSignal)
expect(code).toBe(0)
}
describe('CLI Usage', () => {
describe('start', () => {
test('should exit when SIGINT is signalled', async () => {
require('console').log('before build')
await fs.remove(join(dir, '.next'))
await nextBuild(dir, undefined, {
onStdout(msg) {
console.log(msg)
},
onStderr(msg) {
console.log(msg)
},
})
require('console').log('build finished')
const port = await findPort()
await testExitSignal(
'SIGINT',
['start', dir, '-p', port],
/started server on/
)
})
test('should exit when SIGTERM is signalled', async () => {
await fs.remove(join(dir, '.next'))
await nextBuild(dir, undefined, {
onStdout(msg) {
console.log(msg)
},
onStderr(msg) {
console.log(msg)
},
})
const port = await findPort()
await testExitSignal(
'SIGTERM',
['start', dir, '-p', port],
/started server on/
)
})
test('--help', async () => {
const help = await runNextCommand(['start', '--help'], {
stdout: true,
})
expect(help.stdout).toMatch(/Starts the application in production mode/)
})
test('-h', async () => {
const help = await runNextCommand(['start', '-h'], {
stdout: true,
})
expect(help.stdout).toMatch(/Starts the application in production mode/)
})
test('should format IPv6 addresses correctly', async () => {
const port = await findPort()
const output = await runNextCommand(
['start', '--hostname', '::', '--port', port],
{
stdout: true,
}
)
expect(output.stdout).toMatch(new RegExp(`on \\[::\\]:${port}`))
expect(output.stdout).toMatch(new RegExp(`http://\\[::1\\]:${port}`))
})
test('should warn when unknown argument provided', async () => {
const { stderr } = await runNextCommand(['start', '--random'], {
stderr: true,
})
expect(stderr).toEqual('Unknown or unexpected option: --random\n')
})
test('should not throw UnhandledPromiseRejectionWarning', async () => {
const { stderr } = await runNextCommand(['start', '--random'], {
stderr: true,
})
expect(stderr).not.toContain('UnhandledPromiseRejectionWarning')
})
test('duplicate sass deps', async () => {
const port = await findPort()
let stderr = ''
let instance = await launchApp(dirDuplicateSass, port, {
stderr: true,
onStderr(msg) {
stderr += msg
},
})
try {
await check(() => stderr, /both `sass` and `node-sass` installed/)
} finally {
await killApp(instance)
}
})
test('invalid directory', async () => {
const output = await runNextCommand(['start', 'non-existent'], {
stderr: true,
})
expect(output.stderr).toContain(
'Invalid project directory provided, no such directory'
)
})
test('--keepAliveTimeout string arg', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout', 'string'],
{
stderr: true,
}
)
expect(stderr).toContain(
'Invalid --keepAliveTimeout, expected a non negative number but received "NaN"'
)
})
test('--keepAliveTimeout negative number', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout=-100'],
{
stderr: true,
}
)
expect(stderr).toContain(
'Invalid --keepAliveTimeout, expected a non negative number but received "-100"'
)
})
test('--keepAliveTimeout Infinity', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout', 'Infinity'],
{
stderr: true,
}
)
expect(stderr).toContain(
'Invalid --keepAliveTimeout, expected a non negative number but received "Infinity"'
)
})
test('--keepAliveTimeout happy path', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout', '100'],
{
stderr: true,
}
)
expect(stderr).not.toContain(
'Invalid keep alive timeout provided, expected a non negative number'
)
})
})
describe('no command', () => {
test('--help', async () => {
const help = await runNextCommand(['--help'], {
@ -114,32 +299,11 @@ describe('CLI Usage', () => {
})
test('should exit when SIGINT is signalled', async () => {
const killSigint = (instance) =>
setTimeout(() => instance.kill('SIGINT'), 1000)
const { code, signal } = await runNextCommand(['build', dir], {
ignoreFail: true,
instance: killSigint,
})
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitCode = process.platform === `win32` ? null : 0
const expectedExitSignal = process.platform === `win32` ? 'SIGINT' : null
expect(code).toBe(expectedExitCode)
expect(signal).toBe(expectedExitSignal)
await testExitSignal('SIGINT', ['build', dir])
})
test('should exit when SIGTERM is signalled', async () => {
const killSigterm = (instance) =>
setTimeout(() => instance.kill('SIGTERM'), 1000)
const { code, signal } = await runNextCommand(['build', dir], {
ignoreFail: true,
instance: killSigterm,
})
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitCode = process.platform === `win32` ? null : 0
const expectedExitSignal = process.platform === `win32` ? 'SIGTERM' : null
expect(code).toBe(expectedExitCode)
expect(signal).toBe(expectedExitSignal)
await testExitSignal('SIGTERM', ['build', dir])
})
test('invalid directory', async () => {
@ -169,61 +333,113 @@ describe('CLI Usage', () => {
test('custom directory', async () => {
const port = await findPort()
const output = await runNextCommandDev([dir, '--port', port], true)
expect(output).toMatch(/started server/i)
let output = ''
const app = await runNextCommandDev([dir, '--port', port], undefined, {
onStdout(msg) {
output += stripAnsi(msg)
},
})
try {
await check(() => output, /started server/i)
} finally {
await killApp(app)
}
})
test('--port', async () => {
const port = await findPort()
const output = await runNextCommandDev([dir, '--port', port], true)
expect(output).toMatch(new RegExp(`on 0.0.0.0:${port}`))
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
let output = ''
const app = await runNextCommandDev([dir, '--port', port], undefined, {
onStdout(msg) {
output += stripAnsi(msg)
},
})
try {
await check(() => output, new RegExp(`on 0.0.0.0:${port}`))
await check(() => output, new RegExp(`http://localhost:${port}`))
} finally {
await killApp(app)
}
})
test('--port 0', async () => {
const output = await runNextCommandDev([dir, '--port', '0'], true)
const port = await findPort()
let output = ''
const app = await runNextCommandDev([dir, '--port', port], undefined, {
onStdout(msg) {
output += stripAnsi(msg)
},
})
try {
await check(() => output, new RegExp(`on 0.0.0.0:${port}`))
await check(() => output, new RegExp(`http://localhost:${port}`))
} finally {
await killApp(app)
}
const matches = /on 0.0.0.0:(\d+)/.exec(output)
expect(matches).not.toBe(null)
const port = parseInt(matches[1])
const _port = parseInt(matches[1])
// Regression test: port 0 was interpreted as if no port had been
// provided, falling back to 3000.
expect(port).not.toBe(3000)
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
expect(_port).not.toBe(3000)
})
test('PORT=0', async () => {
const output = await runNextCommandDev([dir], true, {
env: { PORT: 0 },
let output = ''
const app = await runNextCommandDev([dir], undefined, {
env: {
PORT: 0,
},
onStdout(msg) {
output += stripAnsi(msg)
},
})
try {
await check(() => output, /on 0.0.0.0:(\d+)/)
const matches = /on 0.0.0.0:(\d+)/.exec(output)
const _port = parseInt(matches[1])
expect(matches).not.toBe(null)
const port = parseInt(matches[1])
// Regression test: port 0 was interpreted as if no port had been
// provided, falling back to 3000.
expect(port).not.toBe(3000)
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
expect(_port).not.toBe(3000)
} finally {
await killApp(app)
}
})
test("NODE_OPTIONS='--inspect'", async () => {
// this test checks that --inspect works by launching a single debugger for the main Next.js process,
// not for its subprocesses
const port = await findPort()
const output = await runNextCommandDev([dir, '--port', port], true, {
let output = ''
const app = await runNextCommandDev([dir, '--port', port], undefined, {
onStdout(msg) {
output += stripAnsi(msg)
},
env: { NODE_OPTIONS: '--inspect' },
})
expect(output).toMatch(new RegExp(`on 0.0.0.0:${port}`))
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
try {
await check(() => output, new RegExp(`on 0.0.0.0:${port}`))
await check(() => output, new RegExp(`http://localhost:${port}`))
} finally {
await killApp(app)
}
})
test('-p', async () => {
const port = await findPort()
const output = await runNextCommandDev([dir, '-p', port], true)
expect(output).toMatch(new RegExp(`on 0.0.0.0:${port}`))
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
let output = ''
const app = await runNextCommandDev([dir, '-p', port], undefined, {
onStdout(msg) {
output += stripAnsi(msg)
},
env: { NODE_OPTIONS: '--inspect' },
})
try {
await check(() => output, new RegExp(`on 0.0.0.0:${port}`))
await check(() => output, new RegExp(`http://localhost:${port}`))
} finally {
await killApp(app)
}
})
test('-p conflict', async () => {
@ -261,32 +477,62 @@ describe('CLI Usage', () => {
test('--hostname', async () => {
const port = await findPort()
const output = await runNextCommandDev(
let output = ''
const app = await runNextCommandDev(
[dir, '--hostname', '0.0.0.0', '--port', port],
true
undefined,
{
onStdout(msg) {
output += stripAnsi(msg)
},
}
)
expect(output).toMatch(new RegExp(`on 0.0.0.0:${port}`))
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
try {
await check(() => output, new RegExp(`on 0.0.0.0:${port}`))
await check(() => output, new RegExp(`http://localhost:${port}`))
} finally {
await killApp(app)
}
})
test('-H', async () => {
const port = await findPort()
const output = await runNextCommandDev(
let output = ''
const app = await runNextCommandDev(
[dir, '-H', '0.0.0.0', '--port', port],
true
undefined,
{
onStdout(msg) {
output += stripAnsi(msg)
},
}
)
expect(output).toMatch(new RegExp(`on 0.0.0.0:${port}`))
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
try {
await check(() => output, new RegExp(`on 0.0.0.0:${port}`))
await check(() => output, new RegExp(`http://localhost:${port}`))
} finally {
await killApp(app)
}
})
test('should format IPv6 addresses correctly', async () => {
const port = await findPort()
const output = await runNextCommandDev(
let output = ''
const app = await runNextCommandDev(
[dir, '--hostname', '::', '--port', port],
true
undefined,
{
onStdout(msg) {
output += stripAnsi(msg)
},
}
)
expect(output).toMatch(new RegExp(`on \\[::\\]:${port}`))
expect(output).toMatch(new RegExp(`http://\\[::1\\]:${port}`))
try {
await check(() => output, new RegExp(`on \\[::\\]:${port}`))
await check(() => output, new RegExp(`http://\\[::1\\]:${port}`))
} finally {
await killApp(app)
}
})
test('should warn when unknown argument provided', async () => {
@ -303,34 +549,20 @@ describe('CLI Usage', () => {
})
test('should exit when SIGINT is signalled', async () => {
const killSigint = (instance) =>
setTimeout(() => instance.kill('SIGINT'), 2000)
const port = await findPort()
const { code, signal } = await runNextCommand(['dev', dir, '-p', port], {
ignoreFail: true,
instance: killSigint,
})
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitCode = process.platform === `win32` ? null : 0
const expectedExitSignal = process.platform === `win32` ? 'SIGINT' : null
expect(code).toBe(expectedExitCode)
expect(signal).toBe(expectedExitSignal)
await testExitSignal(
'SIGINT',
['dev', dir, '-p', port],
/started server on/
)
})
test('should exit when SIGTERM is signalled', async () => {
const killSigterm = (instance) =>
setTimeout(() => instance.kill('SIGTERM'), 2000)
const port = await findPort()
const { code, signal } = await runNextCommand(['dev', dir, '-p', port], {
ignoreFail: true,
instance: killSigterm,
})
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitCode = process.platform === `win32` ? null : 0
const expectedExitSignal = process.platform === `win32` ? 'SIGTERM' : null
expect(code).toBe(expectedExitCode)
expect(signal).toBe(expectedExitSignal)
await testExitSignal(
'SIGTERM',
['dev', dir, '-p', port],
/started server on/
)
})
test('invalid directory', async () => {
@ -343,161 +575,6 @@ describe('CLI Usage', () => {
})
})
describe('start', () => {
test('--help', async () => {
const help = await runNextCommand(['start', '--help'], {
stdout: true,
})
expect(help.stdout).toMatch(/Starts the application in production mode/)
})
test('-h', async () => {
const help = await runNextCommand(['start', '-h'], {
stdout: true,
})
expect(help.stdout).toMatch(/Starts the application in production mode/)
})
test('should format IPv6 addresses correctly', async () => {
const port = await findPort()
const output = await runNextCommand(
['start', '--hostname', '::', '--port', port],
{
stdout: true,
}
)
expect(output.stdout).toMatch(new RegExp(`on \\[::\\]:${port}`))
expect(output.stdout).toMatch(new RegExp(`http://\\[::1\\]:${port}`))
})
test('should warn when unknown argument provided', async () => {
const { stderr } = await runNextCommand(['start', '--random'], {
stderr: true,
})
expect(stderr).toEqual('Unknown or unexpected option: --random\n')
})
test('should not throw UnhandledPromiseRejectionWarning', async () => {
const { stderr } = await runNextCommand(['start', '--random'], {
stderr: true,
})
expect(stderr).not.toContain('UnhandledPromiseRejectionWarning')
})
test('duplicate sass deps', async () => {
const port = await findPort()
let stderr = ''
let instance = await launchApp(dirDuplicateSass, port, {
stderr: true,
onStderr(msg) {
stderr += msg
},
})
try {
await check(() => stderr, /both `sass` and `node-sass` installed/)
} finally {
await killApp(instance)
}
})
test('should exit when SIGINT is signalled', async () => {
const killSigint = (instance) =>
setTimeout(() => instance.kill('SIGINT'), 1000)
await nextBuild(dir)
const port = await findPort()
const { code, signal } = await runNextCommand(
['start', dir, '-p', port],
{
ignoreFail: true,
instance: killSigint,
}
)
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitCode = process.platform === `win32` ? null : 0
const expectedExitSignal = process.platform === `win32` ? 'SIGINT' : null
expect(code).toBe(expectedExitCode)
expect(signal).toBe(expectedExitSignal)
})
test('should exit when SIGTERM is signalled', async () => {
const killSigterm = (instance) =>
setTimeout(() => instance.kill('SIGTERM'), 1000)
await nextBuild(dir)
const port = await findPort()
const { code, signal } = await runNextCommand(
['start', dir, '-p', port],
{
ignoreFail: true,
instance: killSigterm,
}
)
// Node can only partially emulate signals on Windows. Our signal handlers won't affect the exit code.
// See: https://nodejs.org/api/process.html#process_signal_events
const expectedExitCode = process.platform === `win32` ? null : 0
const expectedExitSignal = process.platform === `win32` ? 'SIGTERM' : null
expect(code).toBe(expectedExitCode)
expect(signal).toBe(expectedExitSignal)
})
test('invalid directory', async () => {
const output = await runNextCommand(['start', 'non-existent'], {
stderr: true,
})
expect(output.stderr).toContain(
'Invalid project directory provided, no such directory'
)
})
test('--keepAliveTimeout string arg', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout', 'string'],
{
stderr: true,
}
)
expect(stderr).toContain(
'Invalid --keepAliveTimeout, expected a non negative number but received "NaN"'
)
})
test('--keepAliveTimeout negative number', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout=-100'],
{
stderr: true,
}
)
expect(stderr).toContain(
'Invalid --keepAliveTimeout, expected a non negative number but received "-100"'
)
})
test('--keepAliveTimeout Infinity', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout', 'Infinity'],
{
stderr: true,
}
)
expect(stderr).toContain(
'Invalid --keepAliveTimeout, expected a non negative number but received "Infinity"'
)
})
test('--keepAliveTimeout happy path', async () => {
const { stderr } = await runNextCommand(
['start', '--keepAliveTimeout', '100'],
{
stderr: true,
}
)
expect(stderr).not.toContain(
'Invalid keep alive timeout provided, expected a non negative number'
)
})
})
describe('export', () => {
test('--help', async () => {
const help = await runNextCommand(['export', '--help'], {

View file

@ -110,6 +110,12 @@ export class Playwright extends BrowserInterface {
await oldPage.close()
}
page = await context.newPage()
// in development compilation can take longer due to
// lower CPU availability in GH actions
page.setDefaultTimeout(60 * 1000)
page.setDefaultNavigationTimeout(60 * 1000)
pageLogs = []
websocketFrames = []