From 242837570832486e23227fc361ab9bbd73fd02c2 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:53:59 +0200 Subject: [PATCH 1/5] Fix test for Turbopack --- test/integration/image-optimizer/test/util.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/integration/image-optimizer/test/util.ts b/test/integration/image-optimizer/test/util.ts index a5b1c7f96c129..ab5dd3ca5d779 100644 --- a/test/integration/image-optimizer/test/util.ts +++ b/test/integration/image-optimizer/test/util.ts @@ -1439,9 +1439,12 @@ export function runTests(ctx: RunTestsCtx) { it('should set cache-control to immutable for static images', async () => { if (!ctx.isDev) { - const filename = 'test' + const filename = fs + .readdirSync(join(ctx.appDir, '.next/static/media')) + .find((f) => /^test\.[0-9a-f]+\.jpg$/.test(f)) + expect(filename).toBeString() const query = { - url: `/_next/static/media/${filename}.fab2915d.jpg`, + url: `/_next/static/media/${filename}`, w: ctx.w, q: ctx.q, } @@ -1454,7 +1457,7 @@ export function runTests(ctx: RunTestsCtx) { ) expect(res1.headers.get('Vary')).toBe('Accept') expect(res1.headers.get('Content-Disposition')).toBe( - `${contentDispositionType}; filename="${filename}.webp"` + `${contentDispositionType}; filename="test.webp"` ) await expectWidth(res1, ctx.w) @@ -1466,7 +1469,7 @@ export function runTests(ctx: RunTestsCtx) { ) expect(res2.headers.get('Vary')).toBe('Accept') expect(res2.headers.get('Content-Disposition')).toBe( - `${contentDispositionType}; filename="${filename}.webp"` + `${contentDispositionType}; filename="test.webp"` ) await expectWidth(res2, ctx.w) } From e8b965501d0de4be078944b94c20c576be52822e Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:08:46 +0200 Subject: [PATCH 2/5] Remove special Turbopack casing in tests --- .../404-page-app/test/index.test.js | 114 +- .../404-page-custom-error/test/index.test.js | 48 +- .../404-page-ssg/test/index.test.js | 102 +- test/integration/404-page/test/index.test.js | 229 ++- .../500-page/test/gsp-gssp.test.js | 310 ++-- test/integration/500-page/test/index.test.js | 413 +++--- .../absolute-assetprefix/test/index.test.js | 215 ++- .../test/index.test.js | 37 +- .../api-catch-all/test/index.test.js | 21 +- .../api-support/test/index.test.js | 23 +- .../app-dir-export/test/config.test.ts | 135 +- .../test/dynamic-missing-gsp-dev.test.ts | 59 +- .../test/dynamic-missing-gsp-prod.test.ts | 43 +- .../test/dynamicapiroute-dev.test.ts | 45 +- .../test/dynamicapiroute-prod.test.ts | 45 +- .../test/dynamicpage-dev.test.ts | 37 +- .../test/dynamicpage-prod.test.ts | 37 +- .../app-dir-export/test/start.test.ts | 85 +- .../test/trailing-slash-dev.test.ts | 19 +- .../test/trailing-slash-start.test.ts | 19 +- .../test/index.test.js | 72 +- .../test/index.test.js | 43 +- .../app-dynamic-error/test/index.test.ts | 27 +- test/integration/app-tree/test/index.test.js | 40 +- .../auto-export-error-bail/test/index.test.js | 9 +- .../test/index.test.js | 25 +- .../auto-export/test/index.test.js | 25 +- .../test/index.test.js | 23 +- test/integration/bigint/test/index.test.js | 42 +- .../build-output/test/index.test.js | 455 +++--- .../test/index.test.ts | 39 +- .../test/index.test.js | 169 ++- .../test/index.test.js | 261 ++-- .../build-warnings/test/index.test.js | 169 ++- .../test/index.test.js | 38 +- test/integration/chunking/test/index.test.js | 201 ++- .../clean-distdir/test/index.test.js | 47 +- test/integration/cli/test/index.test.js | 461 +++--- .../integration/client-404/test/index.test.js | 44 +- .../client-shallow-routing/test/index.test.js | 44 +- .../test/index.test.js | 97 +- .../config-promise-error/test/index.test.js | 33 +- .../config-syntax-error/test/index.test.js | 63 +- .../config-validation/test/index.test.ts | 109 +- .../test/index.test.js | 85 +- .../conflicting-ssg-paths/test/index.test.js | 167 ++- .../critical-css/test/index.test.js | 43 +- .../css-client-nav/test/index.test.js | 131 +- .../css-customization/test/index.test.js | 557 ++++--- .../css-features/test/browserslist.test.js | 190 ++- .../css-features/test/css-modules.test.js | 231 ++- .../css-features/test/index.test.js | 207 ++- .../integration/css-minify/test/index.test.js | 25 +- .../css-modules/test/index.test.js | 1012 +++++++------ .../css/test/basic-global-support.test.js | 737 +++++----- .../css/test/css-and-styled-jsx.test.js | 61 +- .../css/test/css-compilation.test.js | 675 ++++----- test/integration/css/test/css-modules.test.js | 255 ++-- .../css/test/css-rendering.test.js | 181 ++- .../css/test/valid-invalid-css.test.js | 235 ++- .../test/index.test.js | 43 +- .../custom-error/test/index.test.js | 43 +- .../custom-page-extension/test/index.test.js | 40 +- .../custom-routes-catchall/test/index.test.js | 44 +- .../test/index.test.js | 40 +- .../custom-routes-i18n/test/index.test.js | 40 +- .../custom-routes/test/index.test.js | 171 +-- .../custom-server/test/index.test.js | 80 +- .../data-fetching-errors/test/index.test.js | 64 +- .../dedupes-scripts/test/index.test.js | 49 +- .../integration/disable-js/test/index.test.js | 144 +- test/integration/dist-dir/test/index.test.js | 117 +- .../test/index.test.js | 103 +- .../document-head-warnings/test/index.test.js | 37 +- .../integration/draft-mode/test/index.test.ts | 434 +++--- .../test/index.test.js | 52 +- .../test/index.test.js | 48 +- .../test/index.test.js | 114 +- .../dynamic-routing/test/index.test.js | 54 +- .../test/index.test.js | 212 ++- .../test/index.test.js | 401 +++-- .../test/index.test.js | 235 ++- .../test/module-imports.test.js | 144 +- .../test/index.test.js | 35 +- .../test/index.test.ts | 36 +- .../test/index.test.ts | 138 +- .../integration/env-config/test/index.test.js | 424 +++--- .../error-in-error/test/index.test.js | 41 +- .../error-load-fail/test/index.test.js | 59 +- .../test/index.test.js | 49 +- .../test/index.test.js | 23 +- .../eslint/test/next-build.test.js | 299 ++-- .../integration/export-404/test/index.test.js | 62 +- .../export-default-map/test/index.test.js | 107 +- .../export-dynamic-pages/test/index.test.js | 59 +- .../test/index.test.js | 33 +- .../test/index.test.js | 19 +- .../export-image-default/test/index.test.js | 25 +- .../test/index.test.js | 238 ++- .../export-image-loader/test/index.test.js | 307 ++-- .../test/index.test.ts | 19 +- .../export-intent/test/index.test.js | 311 ++-- .../export-subfolders/test/index.test.js | 49 +- .../externals-esm-loose/test/index.test.js | 49 +- .../externals-pages-bundle/test/index.test.js | 101 +- .../fallback-false-rewrite/test/index.test.js | 48 +- .../fallback-modules/test/index.test.js | 99 +- .../fallback-route-params/test/index.test.js | 44 +- .../test/index.test.js | 68 +- .../fetch-polyfill/test/index.test.js | 68 +- .../file-serving/test/index.test.js | 78 +- .../firebase-grpc/test/index.test.js | 59 +- test/integration/future/test/index.test.js | 37 +- .../getinitialprops/test/index.test.js | 44 +- .../test/index.test.js | 17 +- .../test/index.test.js | 197 ++- .../gip-identifier/test/index.test.js | 18 +- .../gsp-build-errors/test/index.test.js | 111 +- .../gsp-extension/test/index.test.js | 84 +- .../gssp-pageProps-merge/test/index.test.js | 48 +- .../test/index.test.js | 76 +- .../gssp-redirect/test/index.test.js | 98 +- .../handles-export-errors/test/index.test.js | 41 +- test/integration/hashbang/test/index.test.js | 42 +- .../hydrate-then-render/test/index.test.ts | 49 +- test/integration/hydration/test/index.test.js | 44 +- .../i18n-support-base-path/test/index.test.js | 213 ++- .../i18n-support-catchall/test/index.test.js | 50 +- .../test/index.test.js | 40 +- .../test/index.test.js | 56 +- .../test/index.test.js | 56 +- .../test/index.test.js | 40 +- .../test/index.test.js | 40 +- .../i18n-support/test/index.test.js | 494 +++---- .../image-generation/test/index.test.ts | 51 +- .../image-optimizer/test/index.test.ts | 234 ++- test/integration/image-optimizer/test/util.ts | 8 +- .../index-index/test/index.test.ts | 57 +- .../initial-ref/test/index.test.js | 40 +- .../invalid-config-values/test/index.test.js | 45 +- .../invalid-custom-routes/test/index.test.js | 64 +- .../test/index.test.js | 77 +- .../invalid-href/test/index.test.ts | 246 ++-- .../test/index.test.js | 48 +- .../invalid-multi-match/test/index.test.js | 52 +- .../test/index.test.js | 75 +- .../jsconfig-baseurl/test/index.test.js | 37 +- .../jsconfig-empty/test/index.test.js | 19 +- .../jsconfig-paths/test/index.test.js | 83 +- test/integration/jsconfig/test/index.test.js | 63 +- .../test/index.test.js | 17 +- .../link-ref-app/test/index.test.js | 116 +- .../link-ref-pages/test/index.test.js | 116 +- .../link-without-router/test/index.test.js | 32 +- .../middleware-basic/test/index.test.js | 52 +- .../test/index.test.js | 117 +- .../test/index.test.ts | 51 +- .../middleware-prefetch/tests/index.test.js | 127 +- .../middleware-src-node/test/index.test.js | 60 +- .../middleware-src/test/index.test.js | 60 +- .../test/index.test.js | 161 +- .../integration/module-ids/test/index.test.js | 206 +-- .../test/index.test.js | 214 ++- .../next-dynamic-css/test/index.test.js | 40 +- .../test/index.test.js | 50 +- .../next-dynamic/test/index.test.js | 50 +- .../asset-prefix/test/index.test.ts | 102 +- .../base-path/test/index.test.ts | 40 +- .../base-path/test/static.test.ts | 89 +- .../basic/test/index.test.ts | 229 ++- .../custom-resolver/test/index.test.ts | 47 +- .../default/test/index.test.ts | 48 +- .../default/test/static.test.ts | 76 +- .../test/index.test.ts | 25 +- .../test/index.test.ts | 95 +- .../noscript/test/index.test.ts | 49 +- .../react-virtualized/test/index.test.ts | 103 +- .../trailing-slash/test/index.test.ts | 100 +- .../typescript/test/index.test.ts | 109 +- .../unicode/test/index.test.ts | 64 +- .../unoptimized/test/index.test.ts | 48 +- .../test/index.test.ts | 25 +- .../app-dir-localpatterns/test/index.test.ts | 48 +- .../app-dir-qualities/test/index.test.ts | 48 +- .../next-image-new/app-dir/test/index.test.ts | 48 +- .../app-dir/test/static.test.ts | 107 +- .../asset-prefix/test/index.test.js | 140 +- .../base-path/test/index.test.js | 52 +- .../base-path/test/static.test.js | 105 +- .../test/index.test.ts | 40 +- .../next-image-new/default/test/index.test.ts | 48 +- .../default/test/static.test.ts | 97 +- .../export-config/test/index.test.ts | 45 +- .../test/index.test.ts | 25 +- .../invalid-image-import/test/index.test.ts | 64 +- .../test/index.test.ts | 50 +- .../test/index.test.ts | 64 +- .../loader-config/test/index.test.ts | 50 +- .../middleware/test/index.test.ts | 47 +- .../middleware-intercept-next-image.test.ts | 45 +- .../react-virtualized/test/index.test.ts | 103 +- .../trailing-slash/test/index.test.ts | 100 +- .../typescript/test/index.test.ts | 109 +- .../next-image-new/unicode/test/index.test.ts | 64 +- .../unoptimized/test/index.test.ts | 50 +- .../no-op-export/test/index.test.js | 75 +- .../no-page-props/test/index.test.js | 44 +- .../node-fetch-keep-alive/test/index.test.js | 47 +- .../non-next-dist-exclude/test/index.test.js | 21 +- .../test/index.test.js | 111 +- .../not-found-revalidate/test/index.test.js | 29 +- .../nullish-config/test/index.test.js | 54 +- .../numeric-sep/test/index.test.js | 25 +- .../test/index.test.js | 40 +- .../page-config/test/index.test.js | 213 ++- .../page-extensions/test/index.test.js | 98 +- .../polyfilling-minimal/test/index.test.js | 25 +- test/integration/polyfills/test/index.test.js | 85 +- .../port-env-var/test/index.test.js | 54 +- .../preload-viewport/test/index.test.js | 937 ++++++------ .../prerender-export/test/index.test.js | 73 +- .../test/index.test.js | 50 +- .../test/index.test.js | 21 +- .../test/index.test.js | 25 +- .../test/index.test.js | 41 +- .../prerender-preview/test/index.test.js | 223 ++- .../prerender-revalidate/test/index.test.js | 80 +- .../preview-fallback/test/index.test.js | 42 +- .../production-build-dir/test/index.test.js | 35 +- .../production-config/test/index.test.js | 97 +- .../production-nav/test/index.test.js | 45 +- .../query-with-encoding/test/index.test.js | 463 +++--- .../test/index.test.js | 59 +- .../react-profiling-mode/test/index.test.js | 95 +- .../test/index.test.js | 88 +- .../test/index.test.js | 44 +- .../test/index.test.js | 49 +- .../with-get-initial-props/test/index.test.js | 49 +- .../test/index.test.js | 49 +- .../repeated-slashes/test/index.test.js | 98 +- .../test/index.test.js | 1204 ++++++++------- .../revalidate-as-path/test/index.test.js | 33 +- .../test/index.test.js | 44 +- .../test/index.test.js | 40 +- .../test/index.test.js | 40 +- .../rewrites-has-condition/test/index.test.js | 40 +- .../test/index.test.js | 44 +- .../root-catchall-cache/test/index.test.js | 21 +- .../test/index.test.js | 21 +- .../route-index/test/index.test.js | 40 +- .../route-indexes/test/index.test.js | 44 +- .../route-load-cancel-css/test/index.test.js | 33 +- .../route-load-cancel/test/index.test.js | 50 +- .../router-hash-navigation/test/index.test.js | 44 +- .../test/index.test.js | 46 +- .../router-is-ready/test/index.test.js | 52 +- .../router-prefetch/test/index.test.js | 74 +- .../router-rerender/test/index.test.js | 44 +- .../script-loader/test/index.test.ts | 43 +- .../test/index.test.js | 40 +- .../test/index.test.js | 44 +- .../server-asset-modules/test/index.test.js | 46 +- .../test/index.test.js | 46 +- .../src-dir-support/test/index.test.js | 40 +- .../ssg-data-404/test/index.test.js | 128 +- .../test/index.test.js | 50 +- .../integration/static-404/test/index.test.js | 55 +- .../static-page-name/test/index.test.js | 40 +- .../styled-jsx-plugin/test/index.test.js | 31 +- .../integration/telemetry/test/config.test.js | 1301 ++++++++--------- test/integration/telemetry/test/index.test.js | 492 ++++--- .../telemetry/test/page-features.test.js | 253 ++-- .../trailing-slash-dist/test/index.test.js | 19 +- .../test/index.test.js | 44 +- .../test/index.test.js | 96 +- .../tsconfig-verifier/test/index.test.js | 440 +++--- .../turborepo-access-trace/test/index.test.js | 51 +- .../test/index.test.js | 135 +- .../typeof-window-replace/test/index.test.js | 133 +- .../test/index.test.js | 19 +- .../test/index.test.js | 25 +- .../test/index.test.js | 111 +- .../test/index.test.js | 42 +- .../integration/typescript/test/index.test.js | 83 +- .../test/index.test.js | 19 +- .../webpack-require-hook/test/index.test.js | 33 +- .../with-electron/test/index.test.js | 105 +- .../worker-webpack5/test/index.test.js | 40 +- test/lib/next-test-utils.ts | 9 +- .../eslint/test/next-build-and-lint.test.ts | 617 ++++---- .../graceful-shutdown/index.test.ts | 8 +- 291 files changed, 15416 insertions(+), 17101 deletions(-) diff --git a/test/integration/404-page-app/test/index.test.js b/test/integration/404-page-app/test/index.test.js index 48ab47a17af7b..2414e2cd95635 100644 --- a/test/integration/404-page-app/test/index.test.js +++ b/test/integration/404-page-app/test/index.test.js @@ -21,73 +21,67 @@ let appPort let app describe('404 Page Support with _app', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - afterAll(() => killApp(app)) + describe('production mode', () => { + afterAll(() => killApp(app)) - it('should build successfully', async () => { - const { code, stderr, stdout } = await nextBuild(appDir, [], { - stderr: true, - stdout: true, - }) + it('should build successfully', async () => { + const { code, stderr, stdout } = await nextBuild(appDir, [], { + stderr: true, + stdout: true, + }) - expect(code).toBe(0) - expect(stderr).not.toMatch(gip404Err) - expect(stdout).not.toMatch(gip404Err) + expect(code).toBe(0) + expect(stderr).not.toMatch(gip404Err) + expect(stdout).not.toMatch(gip404Err) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - it('should not output static 404 if _app has getInitialProps', async () => { - const browser = await webdriver(appPort, '/404') - const isAutoExported = await browser.eval('__NEXT_DATA__.autoExport') - expect(isAutoExported).toBeFalsy() - }) + it('should not output static 404 if _app has getInitialProps', async () => { + const browser = await webdriver(appPort, '/404') + const isAutoExported = await browser.eval('__NEXT_DATA__.autoExport') + expect(isAutoExported).toBeFalsy() + }) - it('specify to use the 404 page still in the routes-manifest', async () => { - const manifest = await fs.readJSON( - join(appDir, '.next/routes-manifest.json') - ) - expect(manifest.pages404).toBe(true) - }) + it('specify to use the 404 page still in the routes-manifest', async () => { + const manifest = await fs.readJSON( + join(appDir, '.next/routes-manifest.json') + ) + expect(manifest.pages404).toBe(true) + }) - it('should still use 404 page', async () => { - const res = await fetchViaHTTP(appPort, '/abc') - expect(res.status).toBe(404) - const $ = cheerio.load(await res.text()) - expect($('#404-title').text()).toBe('Hi There') - }) - } - ) - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - let stderr = '' - let stdout = '' + it('should still use 404 page', async () => { + const res = await fetchViaHTTP(appPort, '/abc') + expect(res.status).toBe(404) + const $ = cheerio.load(await res.text()) + expect($('#404-title').text()).toBe('Hi There') + }) + }) + describe('development mode', () => { + let stderr = '' + let stdout = '' - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort, { - onStderr(msg) { - stderr += msg - }, - onStdout(msg) { - stdout += msg - }, - }) + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort, { + onStderr(msg) { + stderr += msg + }, + onStdout(msg) { + stdout += msg + }, }) - afterAll(() => killApp(app)) + }) + afterAll(() => killApp(app)) - it('should not show pages/404 GIP error if _app has GIP', async () => { - const res = await fetchViaHTTP(appPort, '/abc') - expect(res.status).toBe(404) - const $ = cheerio.load(await res.text()) - expect($('#404-title').text()).toBe('Hi There') - expect(stderr).not.toMatch(gip404Err) - expect(stdout).not.toMatch(gip404Err) - }) - } - ) + it('should not show pages/404 GIP error if _app has GIP', async () => { + const res = await fetchViaHTTP(appPort, '/abc') + expect(res.status).toBe(404) + const $ = cheerio.load(await res.text()) + expect($('#404-title').text()).toBe('Hi There') + expect(stderr).not.toMatch(gip404Err) + expect(stdout).not.toMatch(gip404Err) + }) + }) }) diff --git a/test/integration/404-page-custom-error/test/index.test.js b/test/integration/404-page-custom-error/test/index.test.js index cd4d78f7218a0..2628abeaf6ec2 100644 --- a/test/integration/404-page-custom-error/test/index.test.js +++ b/test/integration/404-page-custom-error/test/index.test.js @@ -51,37 +51,31 @@ const runTests = (mode) => { } describe('Default 404 Page with custom _error', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - afterAll(() => killApp(app)) + describe('production mode', () => { + afterAll(() => killApp(app)) - it('should build successfully', async () => { - const { code } = await nextBuild(appDir, [], { - stderr: true, - stdout: true, - }) + it('should build successfully', async () => { + const { code } = await nextBuild(appDir, [], { + stderr: true, + stdout: true, + }) - expect(code).toBe(0) + expect(code).toBe(0) - appPort = await findPort() + appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + app = await nextStart(appDir, appPort) + }) - runTests('server') - } - ) - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(() => killApp(app)) + runTests('server') + }) + describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests('dev') - } - ) + runTests('dev') + }) }) diff --git a/test/integration/404-page-ssg/test/index.test.js b/test/integration/404-page-ssg/test/index.test.js index 6bd929b3dafb6..fa24dd4b781f0 100644 --- a/test/integration/404-page-ssg/test/index.test.js +++ b/test/integration/404-page-ssg/test/index.test.js @@ -84,62 +84,56 @@ const runTests = (isDev) => { } describe('404 Page Support SSG', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - afterAll(() => killApp(app)) - - it('should build successfully', async () => { - const { - code, - stderr: buildStderr, - stdout: buildStdout, - } = await nextBuild(appDir, [], { - stderr: true, - stdout: true, - }) - - expect(code).toBe(0) - expect(buildStderr).not.toMatch(gip404Err) - expect(buildStdout).not.toMatch(gip404Err) - - appPort = await findPort() - stderr = '' - stdout = '' - - app = await nextStart(appDir, appPort, { - onStdout(msg) { - stdout += msg - }, - onStderr(msg) { - stderr += msg - }, - }) - buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') + describe('production mode', () => { + afterAll(() => killApp(app)) + + it('should build successfully', async () => { + const { + code, + stderr: buildStderr, + stdout: buildStdout, + } = await nextBuild(appDir, [], { + stderr: true, + stdout: true, }) - runTests() - } - ) - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - appPort = await findPort() - stderr = '' - stdout = '' - app = await launchApp(appDir, appPort, { - onStdout(msg) { - stdout += msg - }, - onStderr(msg) { - stderr += msg - }, - }) + expect(code).toBe(0) + expect(buildStderr).not.toMatch(gip404Err) + expect(buildStdout).not.toMatch(gip404Err) + + appPort = await findPort() + stderr = '' + stdout = '' + + app = await nextStart(appDir, appPort, { + onStdout(msg) { + stdout += msg + }, + onStderr(msg) { + stderr += msg + }, }) - afterAll(() => killApp(app)) + buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') + }) + + runTests() + }) + describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + stderr = '' + stdout = '' + app = await launchApp(appDir, appPort, { + onStdout(msg) { + stdout += msg + }, + onStderr(msg) { + stderr += msg + }, + }) + }) + afterAll(() => killApp(app)) - runTests(true) - } - ) + runTests(true) + }) }) diff --git a/test/integration/404-page/test/index.test.js b/test/integration/404-page/test/index.test.js index 5a59b227ee1eb..8f8391d22cb63 100644 --- a/test/integration/404-page/test/index.test.js +++ b/test/integration/404-page/test/index.test.js @@ -70,18 +70,15 @@ const runTests = (mode = 'server') => { } describe('404 Page Support', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(() => killApp(app)) + describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests('dev') - } - ) + runTests('dev') + }) describe('development mode 2', () => { it('falls back to _error correctly without pages/404', async () => { await fs.move(pages404, `${pages404}.bak`) @@ -183,143 +180,137 @@ describe('404 Page Support', () => { expect(stderr).toMatch(gip404Err) }) }) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - - runTests('server') - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should not cache for custom 404 page with gssp and revalidate disabled', async () => { - await fs.move(pages404, `${pages404}.bak`) - await fs.writeFile( - pages404, - ` + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests('server') + }) + describe('production mode individual', () => { + it('should not cache for custom 404 page with gssp and revalidate disabled', async () => { + await fs.move(pages404, `${pages404}.bak`) + await fs.writeFile( + pages404, + ` const page = () => 'custom 404 page' export async function getStaticProps() { return { props: {} } } export default page ` - ) - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - const cache404 = await getCacheHeader(appPort, '/404') - const cacheNext = await getCacheHeader(appPort, '/_next/abc') - await fs.remove(pages404) - await fs.move(`${pages404}.bak`, pages404) - await killApp(app) + ) + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + const cache404 = await getCacheHeader(appPort, '/404') + const cacheNext = await getCacheHeader(appPort, '/_next/abc') + await fs.remove(pages404) + await fs.move(`${pages404}.bak`, pages404) + await killApp(app) - expect(cache404).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - expect(cacheNext).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - }) + expect(cache404).toBe( + 'private, no-cache, no-store, max-age=0, must-revalidate' + ) + expect(cacheNext).toBe( + 'private, no-cache, no-store, max-age=0, must-revalidate' + ) + }) - it('should not cache for custom 404 page with gssp and revalidate enabled', async () => { - await fs.move(pages404, `${pages404}.bak`) - await fs.writeFile( - pages404, - ` + it('should not cache for custom 404 page with gssp and revalidate enabled', async () => { + await fs.move(pages404, `${pages404}.bak`) + await fs.writeFile( + pages404, + ` const page = () => 'custom 404 page' export async function getStaticProps() { return { props: {}, revalidate: 1 } } export default page ` - ) - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - const cache404 = await getCacheHeader(appPort, '/404') - const cacheNext = await getCacheHeader(appPort, '/_next/abc') - await fs.remove(pages404) - await fs.move(`${pages404}.bak`, pages404) - await killApp(app) + ) + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + const cache404 = await getCacheHeader(appPort, '/404') + const cacheNext = await getCacheHeader(appPort, '/_next/abc') + await fs.remove(pages404) + await fs.move(`${pages404}.bak`, pages404) + await killApp(app) - expect(cache404).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - expect(cacheNext).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - }) + expect(cache404).toBe( + 'private, no-cache, no-store, max-age=0, must-revalidate' + ) + expect(cacheNext).toBe( + 'private, no-cache, no-store, max-age=0, must-revalidate' + ) + }) - it('should not cache for custom 404 page without gssp', async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - const cache404 = await getCacheHeader(appPort, '/404') - const cacheNext = await getCacheHeader(appPort, '/_next/abc') - await killApp(app) + it('should not cache for custom 404 page without gssp', async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + const cache404 = await getCacheHeader(appPort, '/404') + const cacheNext = await getCacheHeader(appPort, '/_next/abc') + await killApp(app) - expect(cache404).toBe(null) - expect(cacheNext).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - }) + expect(cache404).toBe(null) + expect(cacheNext).toBe( + 'private, no-cache, no-store, max-age=0, must-revalidate' + ) + }) - it('shows error with getInitialProps in pages/404 build', async () => { - await fs.move(pages404, `${pages404}.bak`) - await fs.writeFile( - pages404, - ` + it('shows error with getInitialProps in pages/404 build', async () => { + await fs.move(pages404, `${pages404}.bak`) + await fs.writeFile( + pages404, + ` const page = () => 'custom 404 page' page.getInitialProps = () => ({ a: 'b' }) export default page ` - ) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.remove(pages404) - await fs.move(`${pages404}.bak`, pages404) + ) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.remove(pages404) + await fs.move(`${pages404}.bak`, pages404) - expect(stderr).toMatch(gip404Err) - expect(code).toBe(1) - }) + expect(stderr).toMatch(gip404Err) + expect(code).toBe(1) + }) - it('does not show error with getStaticProps in pages/404 build', async () => { - await fs.move(pages404, `${pages404}.bak`) - await fs.writeFile( - pages404, - ` + it('does not show error with getStaticProps in pages/404 build', async () => { + await fs.move(pages404, `${pages404}.bak`) + await fs.writeFile( + pages404, + ` const page = () => 'custom 404 page' export const getStaticProps = () => ({ props: { a: 'b' } }) export default page ` - ) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.remove(pages404) - await fs.move(`${pages404}.bak`, pages404) + ) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.remove(pages404) + await fs.move(`${pages404}.bak`, pages404) - expect(stderr).not.toMatch(gip404Err) - expect(code).toBe(0) - }) + expect(stderr).not.toMatch(gip404Err) + expect(code).toBe(0) + }) - it('shows error with getServerSideProps in pages/404 build', async () => { - await fs.move(pages404, `${pages404}.bak`) - await fs.writeFile( - pages404, - ` + it('shows error with getServerSideProps in pages/404 build', async () => { + await fs.move(pages404, `${pages404}.bak`) + await fs.writeFile( + pages404, + ` const page = () => 'custom 404 page' export const getServerSideProps = () => ({ props: { a: 'b' } }) export default page ` - ) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.remove(pages404) - await fs.move(`${pages404}.bak`, pages404) + ) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.remove(pages404) + await fs.move(`${pages404}.bak`, pages404) - expect(stderr).toMatch(gip404Err) - expect(code).toBe(1) - }) - } - ) + expect(stderr).toMatch(gip404Err) + expect(code).toBe(1) + }) + }) }) diff --git a/test/integration/500-page/test/gsp-gssp.test.js b/test/integration/500-page/test/gsp-gssp.test.js index 2e65116210fdc..4ae344118740b 100644 --- a/test/integration/500-page/test/gsp-gssp.test.js +++ b/test/integration/500-page/test/gsp-gssp.test.js @@ -23,61 +23,59 @@ let appPort let app describe('gsp-gssp', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('does not show error with getStaticProps in pages/500 build', async () => { - await fs.move(pages500, `${pages500}.bak`) - await fs.writeFile( - pages500, - ` + describe('production mode', () => { + it('does not show error with getStaticProps in pages/500 build', async () => { + await fs.move(pages500, `${pages500}.bak`) + await fs.writeFile( + pages500, + ` const page = () => 'custom 500 page' export const getStaticProps = () => ({ props: { a: 'b' } }) export default page ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.remove(pages500) - await fs.move(`${pages500}.bak`, pages500) - - expect(stderr).not.toMatch(gip500Err) - expect(code).toBe(0) - }) - it('shows error with getServerSideProps in pages/500 build', async () => { - await fs.move(pages500, `${pages500}.bak`) - await fs.writeFile( - pages500, - ` + ) + await fs.remove(join(appDir, '.next')) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.remove(pages500) + await fs.move(`${pages500}.bak`, pages500) + + expect(stderr).not.toMatch(gip500Err) + expect(code).toBe(0) + }) + it('shows error with getServerSideProps in pages/500 build', async () => { + await fs.move(pages500, `${pages500}.bak`) + await fs.writeFile( + pages500, + ` const page = () => 'custom 500 page' export const getServerSideProps = () => ({ props: { a: 'b' } }) export default page ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.remove(pages500) - await fs.move(`${pages500}.bak`, pages500) - - expect(stderr).toMatch(gip500Err) - expect(code).toBe(1) - }) - - it('does build 500 statically with getInitialProps in _app and getStaticProps in pages/500', async () => { - await fs.writeFile( - pagesApp, - ` + ) + await fs.remove(join(appDir, '.next')) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.remove(pages500) + await fs.move(`${pages500}.bak`, pages500) + + expect(stderr).toMatch(gip500Err) + expect(code).toBe(1) + }) + + it('does build 500 statically with getInitialProps in _app and getStaticProps in pages/500', async () => { + await fs.writeFile( + pagesApp, + ` import App from 'next/app' const page = ({ Component, pageProps }) => page.getInitialProps = (ctx) => App.getInitialProps(ctx) export default page ` - ) - await fs.rename(pages500, `${pages500}.bak`) - await fs.writeFile( - pages500, - ` + ) + await fs.rename(pages500, `${pages500}.bak`) + await fs.writeFile( + pages500, + ` const page = () => { console.log('rendered 500') return 'custom 500 page' @@ -90,50 +88,50 @@ describe('gsp-gssp', () => { } } ` - ) - await fs.remove(join(appDir, '.next')) - const { - stderr, - stdout: buildStdout, - code, - } = await nextBuild(appDir, [], { - stderr: true, - stdout: true, - }) - - await fs.remove(pagesApp) - await fs.remove(pages500) - await fs.rename(`${pages500}.bak`, pages500) - - expect(stderr).not.toMatch(gip500Err) - expect(buildStdout).toContain('rendered 500') - expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(true) - - let appStdout = '' - const appPort = await findPort() - const app = await nextStart(appDir, appPort, { - onStdout(msg) { - appStdout += msg || '' - }, - onStderr(msg) { - appStdout += msg || '' - }, - }) - - await renderViaHTTP(appPort, '/err') - await killApp(app) - - expect(appStdout).not.toContain('rendered 500') + ) + await fs.remove(join(appDir, '.next')) + const { + stderr, + stdout: buildStdout, + code, + } = await nextBuild(appDir, [], { + stderr: true, + stdout: true, + }) + + await fs.remove(pagesApp) + await fs.remove(pages500) + await fs.rename(`${pages500}.bak`, pages500) + + expect(stderr).not.toMatch(gip500Err) + expect(buildStdout).toContain('rendered 500') + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(true) + + let appStdout = '' + const appPort = await findPort() + const app = await nextStart(appDir, appPort, { + onStdout(msg) { + appStdout += msg || '' + }, + onStderr(msg) { + appStdout += msg || '' + }, }) - it('does not build 500 statically with no pages/500 and getServerSideProps in _error', async () => { - await fs.rename(pages500, `${pages500}.bak`) - await fs.writeFile( - pagesError, - ` + await renderViaHTTP(appPort, '/err') + await killApp(app) + + expect(appStdout).not.toContain('rendered 500') + }) + + it('does not build 500 statically with no pages/500 and getServerSideProps in _error', async () => { + await fs.rename(pages500, `${pages500}.bak`) + await fs.writeFile( + pagesError, + ` function Error({ statusCode }) { return

Error status: {statusCode}

} @@ -154,95 +152,91 @@ describe('gsp-gssp', () => { export default Error ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr: buildStderr, code } = await nextBuild(appDir, [], { - stderr: true, - }) - await fs.rename(`${pages500}.bak`, pages500) - await fs.remove(pagesError) - console.log(buildStderr) - expect(buildStderr).not.toMatch(gip500Err) - expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(false) - - let appStderr = '' - const appPort = await findPort() - const app = await nextStart(appDir, appPort, { - onStderr(msg) { - appStderr += msg || '' - }, - }) - - await renderViaHTTP(appPort, '/err') - await killApp(app) - - expect(appStderr).toContain('called _error getServerSideProps') + ) + await fs.remove(join(appDir, '.next')) + const { stderr: buildStderr, code } = await nextBuild(appDir, [], { + stderr: true, + }) + await fs.rename(`${pages500}.bak`, pages500) + await fs.remove(pagesError) + console.log(buildStderr) + expect(buildStderr).not.toMatch(gip500Err) + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(false) + + let appStderr = '' + const appPort = await findPort() + const app = await nextStart(appDir, appPort, { + onStderr(msg) { + appStderr += msg || '' + }, }) - } - ) - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it('does not show error with getStaticProps in pages/500 dev', async () => { - await fs.move(pages500, `${pages500}.bak`) - await fs.writeFile( - pages500, - ` + + await renderViaHTTP(appPort, '/err') + await killApp(app) + + expect(appStderr).toContain('called _error getServerSideProps') + }) + }) + describe('development mode', () => { + it('does not show error with getStaticProps in pages/500 dev', async () => { + await fs.move(pages500, `${pages500}.bak`) + await fs.writeFile( + pages500, + ` const page = () => 'custom 500 page' export const getStaticProps = () => ({ props: { a: 'b' } }) export default page ` - ) + ) + + let stderr = '' + appPort = await findPort() + app = await launchApp(appDir, appPort, { + onStderr(msg) { + stderr += msg || '' + }, + }) + await renderViaHTTP(appPort, '/abc') + await waitFor(1000) - let stderr = '' - appPort = await findPort() - app = await launchApp(appDir, appPort, { - onStderr(msg) { - stderr += msg || '' - }, - }) - await renderViaHTTP(appPort, '/abc') - await waitFor(1000) + await killApp(app) - await killApp(app) + await fs.remove(pages500) + await fs.move(`${pages500}.bak`, pages500) - await fs.remove(pages500) - await fs.move(`${pages500}.bak`, pages500) + expect(stderr).not.toMatch(gip500Err) + }) - expect(stderr).not.toMatch(gip500Err) - }) - - it('shows error with getServerSideProps in pages/500 dev', async () => { - await fs.move(pages500, `${pages500}.bak`) - await fs.writeFile( - pages500, - ` + it('shows error with getServerSideProps in pages/500 dev', async () => { + await fs.move(pages500, `${pages500}.bak`) + await fs.writeFile( + pages500, + ` const page = () => 'custom 500 page' export const getServerSideProps = () => ({ props: { a: 'b' } }) export default page ` - ) - - let stderr = '' - appPort = await findPort() - app = await launchApp(appDir, appPort, { - onStderr(msg) { - stderr += msg || '' - }, - }) - await renderViaHTTP(appPort, '/500') - await waitFor(1000) + ) + + let stderr = '' + appPort = await findPort() + app = await launchApp(appDir, appPort, { + onStderr(msg) { + stderr += msg || '' + }, + }) + await renderViaHTTP(appPort, '/500') + await waitFor(1000) - await killApp(app) + await killApp(app) - await fs.remove(pages500) - await fs.move(`${pages500}.bak`, pages500) + await fs.remove(pages500) + await fs.move(`${pages500}.bak`, pages500) - expect(stderr).toMatch(gip500Err) - }) - } - ) + expect(stderr).toMatch(gip500Err) + }) + }) }) diff --git a/test/integration/500-page/test/index.test.js b/test/integration/500-page/test/index.test.js index 2799613d5d29c..6b1404ac59f5f 100644 --- a/test/integration/500-page/test/index.test.js +++ b/test/integration/500-page/test/index.test.js @@ -60,19 +60,16 @@ const runTests = (mode = 'server') => { } describe('500 Page Support', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - await fs.remove(join(appDir, '.next')) - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(() => killApp(app)) + describe('development mode', () => { + beforeAll(async () => { + await fs.remove(join(appDir, '.next')) + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests('dev') - } - ) + runTests('dev') + }) describe('development mode 2', () => { it('shows error with getInitialProps in pages/500 dev', async () => { await fs.move(pages500, `${pages500}.bak`) @@ -103,30 +100,25 @@ describe('500 Page Support', () => { expect(stderr).toMatch(gip500Err) }) }) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await fs.remove(join(appDir, '.next')) - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - - runTests('server') - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode 2', - () => { - it('should have correct cache control for 500 page with getStaticProps', async () => { - const orig500 = await fs.readFile(pages500, 'utf8') - - try { - await fs.writeFile( - pages500, - ` + describe('production mode', () => { + beforeAll(async () => { + await fs.remove(join(appDir, '.next')) + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests('server') + }) + describe('production mode 2', () => { + it('should have correct cache control for 500 page with getStaticProps', async () => { + const orig500 = await fs.readFile(pages500, 'utf8') + + try { + await fs.writeFile( + pages500, + ` export default function Page() { return (

custom 500

@@ -141,145 +133,145 @@ describe('500 Page Support', () => { } } ` - ) - - await fs.remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir, [], { - stderr: true, - stdout: true, - }) - expect(code).toBe(0) - - const appPort = await findPort() - const app = await nextStart(appDir, appPort) - const res = await fetchViaHTTP(appPort, '/err') - - await killApp(app) - expect(res.status).toBe(500) - expect(res.headers.get('cache-control')).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - } finally { - await fs.writeFile(pages500, orig500) - } - }) - - it('does not build 500 statically with getInitialProps in _app', async () => { - await fs.writeFile( - pagesApp, - ` - import App from 'next/app' - - const page = ({ Component, pageProps }) => - page.getInitialProps = (ctx) => App.getInitialProps(ctx) - export default page - ` ) + await fs.remove(join(appDir, '.next')) - const { - stderr, - stdout: buildStdout, - code, - } = await nextBuild(appDir, [], { + const { code } = await nextBuild(appDir, [], { stderr: true, stdout: true, }) - - await fs.remove(pagesApp) - - expect(stderr).not.toMatch(gip500Err) - expect(buildStdout).not.toContain('rendered 500') expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(false) - let appStdout = '' const appPort = await findPort() - const app = await nextStart(appDir, appPort, { - onStdout(msg) { - appStdout += msg || '' - }, - onStderr(msg) { - appStdout += msg || '' - }, - }) + const app = await nextStart(appDir, appPort) + const res = await fetchViaHTTP(appPort, '/err') - await renderViaHTTP(appPort, '/err') await killApp(app) + expect(res.status).toBe(500) + expect(res.headers.get('cache-control')).toBe( + 'private, no-cache, no-store, max-age=0, must-revalidate' + ) + } finally { + await fs.writeFile(pages500, orig500) + } + }) + + it('does not build 500 statically with getInitialProps in _app', async () => { + await fs.writeFile( + pagesApp, + ` + import App from 'next/app' - expect(appStdout).toContain('rendered 500') + const page = ({ Component, pageProps }) => + page.getInitialProps = (ctx) => App.getInitialProps(ctx) + export default page + ` + ) + await fs.remove(join(appDir, '.next')) + const { + stderr, + stdout: buildStdout, + code, + } = await nextBuild(appDir, [], { + stderr: true, + stdout: true, }) - it('builds 500 statically by default with no pages/500', async () => { - await fs.rename(pages500, `${pages500}.bak`) - await fs.remove(join(appDir, '.next')) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.rename(`${pages500}.bak`, pages500) + await fs.remove(pagesApp) - expect(stderr).not.toMatch(gip500Err) - expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(true) - - const pagesManifest = await getPagesManifest(appDir) - await updatePagesManifest( - appDir, - JSON.stringify({ - ...pagesManifest, - '/500': pagesManifest['/404'].replace('/404', '/500'), - }) - ) + expect(stderr).not.toMatch(gip500Err) + expect(buildStdout).not.toContain('rendered 500') + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(false) - // ensure static 500 hydrates correctly - const appPort = await findPort() - const app = await nextStart(appDir, appPort) + let appStdout = '' + const appPort = await findPort() + const app = await nextStart(appDir, appPort, { + onStdout(msg) { + appStdout += msg || '' + }, + onStderr(msg) { + appStdout += msg || '' + }, + }) - try { - const browser = await webdriver(appPort, '/err?hello=world') - const initialTitle = await browser.eval('document.title') + await renderViaHTTP(appPort, '/err') + await killApp(app) - const currentTitle = await browser.eval('document.title') + expect(appStdout).toContain('rendered 500') + }) - expect(initialTitle).toBe(currentTitle) - expect(initialTitle).toBe('500: Internal Server Error') - } finally { - await killApp(app) - } - }) + it('builds 500 statically by default with no pages/500', async () => { + await fs.rename(pages500, `${pages500}.bak`) + await fs.remove(join(appDir, '.next')) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.rename(`${pages500}.bak`, pages500) + + expect(stderr).not.toMatch(gip500Err) + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(true) + + const pagesManifest = await getPagesManifest(appDir) + await updatePagesManifest( + appDir, + JSON.stringify({ + ...pagesManifest, + '/500': pagesManifest['/404'].replace('/404', '/500'), + }) + ) - it('builds 500 statically by default with no pages/500 and custom _error without getInitialProps', async () => { - await fs.rename(pages500, `${pages500}.bak`) - await fs.writeFile( - pagesError, - ` + // ensure static 500 hydrates correctly + const appPort = await findPort() + const app = await nextStart(appDir, appPort) + + try { + const browser = await webdriver(appPort, '/err?hello=world') + const initialTitle = await browser.eval('document.title') + + const currentTitle = await browser.eval('document.title') + + expect(initialTitle).toBe(currentTitle) + expect(initialTitle).toBe('500: Internal Server Error') + } finally { + await killApp(app) + } + }) + + it('builds 500 statically by default with no pages/500 and custom _error without getInitialProps', async () => { + await fs.rename(pages500, `${pages500}.bak`) + await fs.writeFile( + pagesError, + ` function Error({ statusCode }) { return

Error status: {statusCode}

} export default Error ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr: buildStderr, code } = await nextBuild(appDir, [], { - stderr: true, - }) - await fs.rename(`${pages500}.bak`, pages500) - await fs.remove(pagesError) - console.log(buildStderr) - expect(buildStderr).not.toMatch(gip500Err) - expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(true) + ) + await fs.remove(join(appDir, '.next')) + const { stderr: buildStderr, code } = await nextBuild(appDir, [], { + stderr: true, }) + await fs.rename(`${pages500}.bak`, pages500) + await fs.remove(pagesError) + console.log(buildStderr) + expect(buildStderr).not.toMatch(gip500Err) + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(true) + }) - it('does not build 500 statically with no pages/500 and custom getInitialProps in _error', async () => { - await fs.rename(pages500, `${pages500}.bak`) - await fs.writeFile( - pagesError, - ` + it('does not build 500 statically with no pages/500 and custom getInitialProps in _error', async () => { + await fs.rename(pages500, `${pages500}.bak`) + await fs.writeFile( + pagesError, + ` function Error({ statusCode }) { return

Error status: {statusCode}

} @@ -298,39 +290,39 @@ describe('500 Page Support', () => { export default Error ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr: buildStderr, code } = await nextBuild(appDir, [], { - stderr: true, - }) - await fs.rename(`${pages500}.bak`, pages500) - await fs.remove(pagesError) - console.log(buildStderr) - expect(buildStderr).not.toMatch(gip500Err) - expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(false) - - let appStderr = '' - const appPort = await findPort() - const app = await nextStart(appDir, appPort, { - onStderr(msg) { - appStderr += msg || '' - }, - }) + ) + await fs.remove(join(appDir, '.next')) + const { stderr: buildStderr, code } = await nextBuild(appDir, [], { + stderr: true, + }) + await fs.rename(`${pages500}.bak`, pages500) + await fs.remove(pagesError) + console.log(buildStderr) + expect(buildStderr).not.toMatch(gip500Err) + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(false) + + let appStderr = '' + const appPort = await findPort() + const app = await nextStart(appDir, appPort, { + onStderr(msg) { + appStderr += msg || '' + }, + }) - await renderViaHTTP(appPort, '/err') - await killApp(app) + await renderViaHTTP(appPort, '/err') + await killApp(app) - expect(appStderr).toContain('called _error.getInitialProps') - }) + expect(appStderr).toContain('called _error.getInitialProps') + }) - it('does not build 500 statically with no pages/500 and custom getInitialProps in _error and _app', async () => { - await fs.rename(pages500, `${pages500}.bak`) - await fs.writeFile( - pagesError, - ` + it('does not build 500 statically with no pages/500 and custom getInitialProps in _error and _app', async () => { + await fs.rename(pages500, `${pages500}.bak`) + await fs.writeFile( + pagesError, + ` function Error({ statusCode }) { return

Error status: {statusCode}

} @@ -349,10 +341,10 @@ describe('500 Page Support', () => { export default Error ` - ) - await fs.writeFile( - pagesApp, - ` + ) + await fs.writeFile( + pagesApp, + ` function App({ pageProps, Component }) { return } @@ -370,40 +362,39 @@ describe('500 Page Support', () => { export default App ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr: buildStderr, code } = await nextBuild(appDir, [], { - stderr: true, - }) - await fs.rename(`${pages500}.bak`, pages500) - await fs.remove(pagesError) - await fs.remove(pagesApp) - console.log(buildStderr) - expect(buildStderr).not.toMatch(gip500Err) - expect(code).toBe(0) - expect( - await fs.pathExists(join(appDir, '.next/server/pages/500.html')) - ).toBe(false) + ) + await fs.remove(join(appDir, '.next')) + const { stderr: buildStderr, code } = await nextBuild(appDir, [], { + stderr: true, }) + await fs.rename(`${pages500}.bak`, pages500) + await fs.remove(pagesError) + await fs.remove(pagesApp) + console.log(buildStderr) + expect(buildStderr).not.toMatch(gip500Err) + expect(code).toBe(0) + expect( + await fs.pathExists(join(appDir, '.next/server/pages/500.html')) + ).toBe(false) + }) - it('shows error with getInitialProps in pages/500 build', async () => { - await fs.move(pages500, `${pages500}.bak`) - await fs.writeFile( - pages500, - ` + it('shows error with getInitialProps in pages/500 build', async () => { + await fs.move(pages500, `${pages500}.bak`) + await fs.writeFile( + pages500, + ` const page = () => 'custom 500 page' page.getInitialProps = () => ({ a: 'b' }) export default page ` - ) - await fs.remove(join(appDir, '.next')) - const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) - await fs.remove(pages500) - await fs.move(`${pages500}.bak`, pages500) + ) + await fs.remove(join(appDir, '.next')) + const { stderr, code } = await nextBuild(appDir, [], { stderr: true }) + await fs.remove(pages500) + await fs.move(`${pages500}.bak`, pages500) - expect(stderr).toMatch(gip500Err) - expect(code).toBe(1) - }) - } - ) + expect(stderr).toMatch(gip500Err) + expect(code).toBe(1) + }) + }) }) diff --git a/test/integration/absolute-assetprefix/test/index.test.js b/test/integration/absolute-assetprefix/test/index.test.js index 1e159ed090eab..24957ff898403 100644 --- a/test/integration/absolute-assetprefix/test/index.test.js +++ b/test/integration/absolute-assetprefix/test/index.test.js @@ -19,124 +19,121 @@ let cdnAccessLog = [] const nextConfig = new File(path.resolve(__dirname, '../next.config.js')) describe('absolute assetPrefix with path prefix', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - cdnPort = await findPort() - // lightweight http proxy - cdn = http.createServer((clientReq, clientRes) => { - const proxyPath = clientReq.url.slice('/path-prefix'.length) - cdnAccessLog.push(proxyPath) - const proxyReq = http.request( - { - hostname: 'localhost', - port: appPort, - path: proxyPath, - method: clientReq.method, - headers: clientReq.headers, - }, - (proxyRes) => { - // cdn must be configured to allow requests from this origin - proxyRes.headers['Access-Control-Allow-Origin'] = - `http://localhost:${appPort}` - clientRes.writeHead(proxyRes.statusCode, proxyRes.headers) - // [NOTE] if socket doesn't have a handler to error event and if error - // event leaks, node.js ends its process with errored exit code. - // However, there can be failing socket event while running test - // as long as assertion is correct, do not care indiviual socket errors. - proxyRes.on('error', (e) => { - require('console').error(e) - }) - clientRes.on('error', (e) => { - require('console').error(e) - }) + describe('production mode', () => { + beforeAll(async () => { + cdnPort = await findPort() + // lightweight http proxy + cdn = http.createServer((clientReq, clientRes) => { + const proxyPath = clientReq.url.slice('/path-prefix'.length) + cdnAccessLog.push(proxyPath) + const proxyReq = http.request( + { + hostname: 'localhost', + port: appPort, + path: proxyPath, + method: clientReq.method, + headers: clientReq.headers, + }, + (proxyRes) => { + // cdn must be configured to allow requests from this origin + proxyRes.headers['Access-Control-Allow-Origin'] = + `http://localhost:${appPort}` + clientRes.writeHead(proxyRes.statusCode, proxyRes.headers) + // [NOTE] if socket doesn't have a handler to error event and if error + // event leaks, node.js ends its process with errored exit code. + // However, there can be failing socket event while running test + // as long as assertion is correct, do not care indiviual socket errors. + proxyRes.on('error', (e) => { + require('console').error(e) + }) + clientRes.on('error', (e) => { + require('console').error(e) + }) - proxyRes.pipe(clientRes, { end: true }) - } - ) - - proxyReq.on('error', (e) => { - require('console').error(e) - }) - clientReq.on('error', (e) => { - require('console').error(e) - }) - clientReq.pipe(proxyReq, { end: true }) - }) - await new Promise((resolve) => cdn.listen(cdnPort, resolve)) - nextConfig.replace('__CDN_PORT__', cdnPort) - await nextBuild(appDir) - buildId = await fs.readFile( - path.resolve(__dirname, '../.next/BUILD_ID'), - 'utf8' + proxyRes.pipe(clientRes, { end: true }) + } ) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterEach(() => { - cdnAccessLog = [] + proxyReq.on('error', (e) => { + require('console').error(e) + }) + clientReq.on('error', (e) => { + require('console').error(e) + }) + clientReq.pipe(proxyReq, { end: true }) }) + await new Promise((resolve) => cdn.listen(cdnPort, resolve)) + nextConfig.replace('__CDN_PORT__', cdnPort) + await nextBuild(appDir) + buildId = await fs.readFile( + path.resolve(__dirname, '../.next/BUILD_ID'), + 'utf8' + ) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(() => killApp(app)) - afterAll(() => cdn.close()) - afterAll(() => nextConfig.restore()) + afterEach(() => { + cdnAccessLog = [] + }) - it('should not fetch static data from a CDN', async () => { - const browser = await webdriver(appPort, '/') - await browser.waitForElementByCss('#about-link').click() - const prop = await browser.waitForElementByCss('#prop').text() - expect(prop).toBe('hello') - expect(cdnAccessLog).not.toContain(`/_next/data/${buildId}/about.json`) - }) + afterAll(() => killApp(app)) + afterAll(() => cdn.close()) + afterAll(() => nextConfig.restore()) - it('should fetch from cache correctly', async () => { - const browser = await webdriver(appPort, '/') - await browser.eval('window.clientSideNavigated = true') - await browser.waitForElementByCss('#about-link').click() - await browser.waitForElementByCss('#prop') - await browser.back() - await browser.waitForElementByCss('#about-link').click() - const prop = await browser.waitForElementByCss('#prop').text() - expect(prop).toBe('hello') - expect(await browser.eval('window.clientSideNavigated')).toBe(true) - expect( - cdnAccessLog.filter( - (path) => path === `/_next/data/${buildId}/about.json` - ) - ).toHaveLength(0) - }) + it('should not fetch static data from a CDN', async () => { + const browser = await webdriver(appPort, '/') + await browser.waitForElementByCss('#about-link').click() + const prop = await browser.waitForElementByCss('#prop').text() + expect(prop).toBe('hello') + expect(cdnAccessLog).not.toContain(`/_next/data/${buildId}/about.json`) + }) - it('should work with getStaticPaths prerendered', async () => { - const browser = await webdriver(appPort, '/') - await browser.waitForElementByCss('#gsp-prerender-link').click() - const prop = await browser.waitForElementByCss('#prop').text() - expect(prop).toBe('prerendered') - expect(cdnAccessLog).not.toContain( - `/_next/data/${buildId}/gsp-fallback/prerendered.json` + it('should fetch from cache correctly', async () => { + const browser = await webdriver(appPort, '/') + await browser.eval('window.clientSideNavigated = true') + await browser.waitForElementByCss('#about-link').click() + await browser.waitForElementByCss('#prop') + await browser.back() + await browser.waitForElementByCss('#about-link').click() + const prop = await browser.waitForElementByCss('#prop').text() + expect(prop).toBe('hello') + expect(await browser.eval('window.clientSideNavigated')).toBe(true) + expect( + cdnAccessLog.filter( + (path) => path === `/_next/data/${buildId}/about.json` ) - }) + ).toHaveLength(0) + }) - it('should work with getStaticPaths fallback', async () => { - const browser = await webdriver(appPort, '/') - await browser.waitForElementByCss('#gsp-fallback-link').click() - const prop = await browser.waitForElementByCss('#prop').text() - expect(prop).toBe('fallback') - expect(cdnAccessLog).not.toContain( - `/_next/data/${buildId}/gsp-fallback/fallback.json` - ) - }) + it('should work with getStaticPaths prerendered', async () => { + const browser = await webdriver(appPort, '/') + await browser.waitForElementByCss('#gsp-prerender-link').click() + const prop = await browser.waitForElementByCss('#prop').text() + expect(prop).toBe('prerendered') + expect(cdnAccessLog).not.toContain( + `/_next/data/${buildId}/gsp-fallback/prerendered.json` + ) + }) - it('should work with getServerSideProps', async () => { - const browser = await webdriver(appPort, '/') - await browser.waitForElementByCss('#gssp-link').click() - const prop = await browser.waitForElementByCss('#prop').text() - expect(prop).toBe('foo') - expect(cdnAccessLog).not.toContain( - `/_next/data/${buildId}/gssp.json?prop=foo` - ) - }) - } - ) + it('should work with getStaticPaths fallback', async () => { + const browser = await webdriver(appPort, '/') + await browser.waitForElementByCss('#gsp-fallback-link').click() + const prop = await browser.waitForElementByCss('#prop').text() + expect(prop).toBe('fallback') + expect(cdnAccessLog).not.toContain( + `/_next/data/${buildId}/gsp-fallback/fallback.json` + ) + }) + + it('should work with getServerSideProps', async () => { + const browser = await webdriver(appPort, '/') + await browser.waitForElementByCss('#gssp-link').click() + const prop = await browser.waitForElementByCss('#prop').text() + expect(prop).toBe('foo') + expect(cdnAccessLog).not.toContain( + `/_next/data/${buildId}/gssp.json?prop=foo` + ) + }) + }) }) diff --git a/test/integration/amphtml-custom-validator/test/index.test.js b/test/integration/amphtml-custom-validator/test/index.test.js index 2b24372625029..f51b63547c893 100644 --- a/test/integration/amphtml-custom-validator/test/index.test.js +++ b/test/integration/amphtml-custom-validator/test/index.test.js @@ -32,26 +32,23 @@ const appDir = join(__dirname, '../') expect(html).toContain('Hello from AMP') }) }) - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it('should run in development mode successfully', async () => { - let stderr = '' - - appPort = await findPort() - app = await launchApp(appDir, appPort, { - onStderr(msg) { - stderr += msg || '' - }, - }) - - const html = await renderViaHTTP(appPort, '/') - await killApp(app) - - expect(stderr).not.toContain('error') - expect(html).toContain('Hello from AMP') + describe('development mode', () => { + it('should run in development mode successfully', async () => { + let stderr = '' + + appPort = await findPort() + app = await launchApp(appDir, appPort, { + onStderr(msg) { + stderr += msg || '' + }, }) - } - ) + + const html = await renderViaHTTP(appPort, '/') + await killApp(app) + + expect(stderr).not.toContain('error') + expect(html).toContain('Hello from AMP') + }) + }) } ) diff --git a/test/integration/api-catch-all/test/index.test.js b/test/integration/api-catch-all/test/index.test.js index 5fa5829a06c92..0af72a8dc0287 100644 --- a/test/integration/api-catch-all/test/index.test.js +++ b/test/integration/api-catch-all/test/index.test.js @@ -59,17 +59,14 @@ describe('API routes', () => { runTests() }) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests() - } - ) + runTests() + }) }) diff --git a/test/integration/api-support/test/index.test.js b/test/integration/api-support/test/index.test.js index c8650c08e3b02..7c6f9c41c247a 100644 --- a/test/integration/api-support/test/index.test.js +++ b/test/integration/api-support/test/index.test.js @@ -650,18 +650,15 @@ describe('API routes', () => { runTests(true) }) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - mode = 'server' - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + mode = 'server' + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests() - } - ) + runTests() + }) }) diff --git a/test/integration/app-dir-export/test/config.test.ts b/test/integration/app-dir-export/test/config.test.ts index a450e982e2a2f..6cac6ae5b1abd 100644 --- a/test/integration/app-dir-export/test/config.test.ts +++ b/test/integration/app-dir-export/test/config.test.ts @@ -11,84 +11,79 @@ import { } from './utils' describe('app dir - with output export (next dev / next build)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should throw when exportPathMap configured', async () => { - nextConfig.replace( - 'trailingSlash: true,', - `trailingSlash: true, + describe('production mode', () => { + it('should throw when exportPathMap configured', async () => { + nextConfig.replace( + 'trailingSlash: true,', + `trailingSlash: true, exportPathMap: async function (map) { return map },` - ) - await fs.remove(distDir) - await fs.remove(exportDir) - let result = { code: 0, stderr: '' } + ) + await fs.remove(distDir) + await fs.remove(exportDir) + let result = { code: 0, stderr: '' } + try { + result = await nextBuild(appDir, [], { stderr: true }) + } finally { + nextConfig.restore() + } + expect(result.code).toBe(1) + expect(result.stderr).toContain( + 'The "exportPathMap" configuration cannot be used with the "app" directory. Please use generateStaticParams() instead.' + ) + }) + it('should error when running next export', async () => { + await fs.remove(distDir) + await fs.remove(exportDir) + nextConfig.delete() + try { + await nextBuild(appDir) + expect(await getFiles()).toEqual([]) + let stdout = '' + let stderr = '' + let error = undefined try { - result = await nextBuild(appDir, [], { stderr: true }) - } finally { - nextConfig.restore() + await runNextCommand(['export', appDir], { + onStdout(msg) { + stdout += msg + }, + onStderr(msg) { + stderr += msg + }, + }) + } catch (e) { + error = e } - expect(result.code).toBe(1) - expect(result.stderr).toContain( - 'The "exportPathMap" configuration cannot be used with the "app" directory. Please use generateStaticParams() instead.' + expect(error).toBeDefined() + expect(stderr).toContain( + `\`next export\` has been removed in favor of 'output: export' in next.config.js` ) - }) - it('should error when running next export', async () => { + expect(stdout).not.toContain('Export successful. Files written to') + expect(await getFiles()).toEqual([]) + } finally { + nextConfig.restore() await fs.remove(distDir) await fs.remove(exportDir) - nextConfig.delete() - try { - await nextBuild(appDir) - expect(await getFiles()).toEqual([]) - let stdout = '' - let stderr = '' - let error = undefined - try { - await runNextCommand(['export', appDir], { - onStdout(msg) { - stdout += msg - }, - onStderr(msg) { - stderr += msg - }, - }) - } catch (e) { - error = e - } - expect(error).toBeDefined() - expect(stderr).toContain( - `\`next export\` has been removed in favor of 'output: export' in next.config.js` - ) - expect(stdout).not.toContain('Export successful. Files written to') - expect(await getFiles()).toEqual([]) - } finally { - nextConfig.restore() - await fs.remove(distDir) - await fs.remove(exportDir) - } - }) - it('should correctly emit exported assets to config.distDir', async () => { - const outputDir = join(appDir, 'output') + } + }) + it('should correctly emit exported assets to config.distDir', async () => { + const outputDir = join(appDir, 'output') + await fs.remove(distDir) + await fs.remove(outputDir) + nextConfig.replace( + 'trailingSlash: true,', + `trailingSlash: true, + distDir: 'output',` + ) + try { + await nextBuild(appDir) + expect(await getFiles(outputDir)).toEqual(expectedWhenTrailingSlashTrue) + } finally { + nextConfig.restore() await fs.remove(distDir) await fs.remove(outputDir) - nextConfig.replace( - 'trailingSlash: true,', - `trailingSlash: true, - distDir: 'output',` - ) - try { - await nextBuild(appDir) - expect(await getFiles(outputDir)).toEqual( - expectedWhenTrailingSlashTrue - ) - } finally { - nextConfig.restore() - await fs.remove(distDir) - await fs.remove(outputDir) - } - }) - } - ) + } + }) + }) }) diff --git a/test/integration/app-dir-export/test/dynamic-missing-gsp-dev.test.ts b/test/integration/app-dir-export/test/dynamic-missing-gsp-dev.test.ts index c053a5056307b..2b2d70f24e042 100644 --- a/test/integration/app-dir-export/test/dynamic-missing-gsp-dev.test.ts +++ b/test/integration/app-dir-export/test/dynamic-missing-gsp-dev.test.ts @@ -1,40 +1,37 @@ import { runTests } from './utils' describe('app dir - with output export - dynamic missing gsp dev', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it('should error when dynamic route is missing generateStaticParams', async () => { - await runTests({ - isDev: true, - dynamicPage: 'undefined', - generateStaticParamsOpt: 'set noop', - expectedErrMsg: - 'Page "/another/[slug]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.', - }) + describe('development mode', () => { + it('should error when dynamic route is missing generateStaticParams', async () => { + await runTests({ + isDev: true, + dynamicPage: 'undefined', + generateStaticParamsOpt: 'set noop', + expectedErrMsg: + 'Page "/another/[slug]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.', }) + }) - it('should error when dynamic route is set to true', async () => { - await runTests({ - isDev: true, - dynamicPage: 'undefined', - dynamicParams: 'true', - expectedErrMsg: - '"dynamicParams: true" cannot be used with "output: export". See more info here: https://nextjs.org/docs/app/building-your-application/deploying/static-exports', - }) + it('should error when dynamic route is set to true', async () => { + await runTests({ + isDev: true, + dynamicPage: 'undefined', + dynamicParams: 'true', + expectedErrMsg: + '"dynamicParams: true" cannot be used with "output: export". See more info here: https://nextjs.org/docs/app/building-your-application/deploying/static-exports', }) + }) - it('should error when client component has generateStaticParams', async () => { - const expectedErrMsg = process.env.IS_TURBOPACK_TEST - ? 'App pages cannot use both "use client" and export function "generateStaticParams()".' - : 'Page "/another/[slug]/page" cannot use both "use client" and export function "generateStaticParams()".' - await runTests({ - isDev: true, - dynamicPage: 'undefined', - generateStaticParamsOpt: 'set client', - expectedErrMsg, - }) + it('should error when client component has generateStaticParams', async () => { + const expectedErrMsg = process.env.IS_TURBOPACK_TEST + ? 'App pages cannot use both "use client" and export function "generateStaticParams()".' + : 'Page "/another/[slug]/page" cannot use both "use client" and export function "generateStaticParams()".' + await runTests({ + isDev: true, + dynamicPage: 'undefined', + generateStaticParamsOpt: 'set client', + expectedErrMsg, }) - } - ) + }) + }) }) diff --git a/test/integration/app-dir-export/test/dynamic-missing-gsp-prod.test.ts b/test/integration/app-dir-export/test/dynamic-missing-gsp-prod.test.ts index 654754b353ebf..3ca3d4e4c310a 100644 --- a/test/integration/app-dir-export/test/dynamic-missing-gsp-prod.test.ts +++ b/test/integration/app-dir-export/test/dynamic-missing-gsp-prod.test.ts @@ -1,31 +1,28 @@ import { runTests } from './utils' describe('app dir - with output export - dynamic missing gsp prod', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should error when dynamic route is missing generateStaticParams', async () => { - await runTests({ - isDev: false, - dynamicPage: 'undefined', - generateStaticParamsOpt: 'set noop', - expectedErrMsg: - 'Page "/another/[slug]" is missing "generateStaticParams()" so it cannot be used with "output: export" config.', - }) + describe('production mode', () => { + it('should error when dynamic route is missing generateStaticParams', async () => { + await runTests({ + isDev: false, + dynamicPage: 'undefined', + generateStaticParamsOpt: 'set noop', + expectedErrMsg: + 'Page "/another/[slug]" is missing "generateStaticParams()" so it cannot be used with "output: export" config.', }) + }) - it('should error when client component has generateStaticParams', async () => { - const expectedErrMsg = process.env.IS_TURBOPACK_TEST - ? 'App pages cannot use both "use client" and export function "generateStaticParams()".' - : 'Page "/another/[slug]/page" cannot use both "use client" and export function "generateStaticParams()".' + it('should error when client component has generateStaticParams', async () => { + const expectedErrMsg = process.env.IS_TURBOPACK_TEST + ? 'App pages cannot use both "use client" and export function "generateStaticParams()".' + : 'Page "/another/[slug]/page" cannot use both "use client" and export function "generateStaticParams()".' - await runTests({ - isDev: false, - dynamicPage: 'undefined', - generateStaticParamsOpt: 'set client', - expectedErrMsg: expectedErrMsg, - }) + await runTests({ + isDev: false, + dynamicPage: 'undefined', + generateStaticParamsOpt: 'set client', + expectedErrMsg: expectedErrMsg, }) - } - ) + }) + }) }) diff --git a/test/integration/app-dir-export/test/dynamicapiroute-dev.test.ts b/test/integration/app-dir-export/test/dynamicapiroute-dev.test.ts index 46075a5b7f8b1..8c1778f4a2fc3 100644 --- a/test/integration/app-dir-export/test/dynamicapiroute-dev.test.ts +++ b/test/integration/app-dir-export/test/dynamicapiroute-dev.test.ts @@ -1,28 +1,25 @@ import { runTests } from './utils' describe('app dir - with output export - dynamic api route dev', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it.each([ - { - dynamicApiRoute: 'undefined', - expectedErrMsg: - 'export const dynamic = "force-static"/export const revalidate not configured on route', - }, - { dynamicApiRoute: "'error'" }, - { dynamicApiRoute: "'force-static'" }, - { - dynamicApiRoute: "'force-dynamic'", - expectedErrMsg: - 'export const dynamic = "force-dynamic" on page "/api/json" cannot be used with "output: export".', - }, - ])( - 'should work in dev with dynamicApiRoute $dynamicApiRoute', - async ({ dynamicApiRoute, expectedErrMsg }) => { - await runTests({ isDev: true, dynamicApiRoute, expectedErrMsg }) - } - ) - } - ) + describe('development mode', () => { + it.each([ + { + dynamicApiRoute: 'undefined', + expectedErrMsg: + 'export const dynamic = "force-static"/export const revalidate not configured on route', + }, + { dynamicApiRoute: "'error'" }, + { dynamicApiRoute: "'force-static'" }, + { + dynamicApiRoute: "'force-dynamic'", + expectedErrMsg: + 'export const dynamic = "force-dynamic" on page "/api/json" cannot be used with "output: export".', + }, + ])( + 'should work in dev with dynamicApiRoute $dynamicApiRoute', + async ({ dynamicApiRoute, expectedErrMsg }) => { + await runTests({ isDev: true, dynamicApiRoute, expectedErrMsg }) + } + ) + }) }) diff --git a/test/integration/app-dir-export/test/dynamicapiroute-prod.test.ts b/test/integration/app-dir-export/test/dynamicapiroute-prod.test.ts index 3161bffcfd3d3..4eb412f69b313 100644 --- a/test/integration/app-dir-export/test/dynamicapiroute-prod.test.ts +++ b/test/integration/app-dir-export/test/dynamicapiroute-prod.test.ts @@ -1,28 +1,25 @@ import { runTests } from './utils' describe('app dir - with output export - dynamic api route prod', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it.each([ - { - dynamicApiRoute: 'undefined', - expectedErrMsg: - 'export const dynamic = "force-static"/export const revalidate not configured on route', - }, - { dynamicApiRoute: "'error'" }, - { dynamicApiRoute: "'force-static'" }, - { - dynamicApiRoute: "'force-dynamic'", - expectedErrMsg: - 'export const dynamic = "force-dynamic" on page "/api/json" cannot be used with "output: export".', - }, - ])( - 'should work in prod with dynamicApiRoute $dynamicApiRoute', - async ({ dynamicApiRoute, expectedErrMsg }) => { - await runTests({ isDev: false, dynamicApiRoute, expectedErrMsg }) - } - ) - } - ) + describe('production mode', () => { + it.each([ + { + dynamicApiRoute: 'undefined', + expectedErrMsg: + 'export const dynamic = "force-static"/export const revalidate not configured on route', + }, + { dynamicApiRoute: "'error'" }, + { dynamicApiRoute: "'force-static'" }, + { + dynamicApiRoute: "'force-dynamic'", + expectedErrMsg: + 'export const dynamic = "force-dynamic" on page "/api/json" cannot be used with "output: export".', + }, + ])( + 'should work in prod with dynamicApiRoute $dynamicApiRoute', + async ({ dynamicApiRoute, expectedErrMsg }) => { + await runTests({ isDev: false, dynamicApiRoute, expectedErrMsg }) + } + ) + }) }) diff --git a/test/integration/app-dir-export/test/dynamicpage-dev.test.ts b/test/integration/app-dir-export/test/dynamicpage-dev.test.ts index 0220d9c28e298..74ea4a7c308c3 100644 --- a/test/integration/app-dir-export/test/dynamicpage-dev.test.ts +++ b/test/integration/app-dir-export/test/dynamicpage-dev.test.ts @@ -1,24 +1,21 @@ import { runTests } from './utils' describe('app dir - with output export - dynamic page dev', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it.each([ - { dynamicPage: 'undefined' }, - { dynamicPage: "'error'" }, - { dynamicPage: "'force-static'" }, - { - dynamicPage: "'force-dynamic'", - expectedErrMsg: - 'Page with `dynamic = "force-dynamic"` couldn\'t be exported. `output: "export"` requires all pages be renderable statically', - }, - ])( - 'should work in dev with dynamicPage $dynamicPage', - async ({ dynamicPage, expectedErrMsg }) => { - await runTests({ isDev: true, dynamicPage, expectedErrMsg }) - } - ) - } - ) + describe('development mode', () => { + it.each([ + { dynamicPage: 'undefined' }, + { dynamicPage: "'error'" }, + { dynamicPage: "'force-static'" }, + { + dynamicPage: "'force-dynamic'", + expectedErrMsg: + 'Page with `dynamic = "force-dynamic"` couldn\'t be exported. `output: "export"` requires all pages be renderable statically', + }, + ])( + 'should work in dev with dynamicPage $dynamicPage', + async ({ dynamicPage, expectedErrMsg }) => { + await runTests({ isDev: true, dynamicPage, expectedErrMsg }) + } + ) + }) }) diff --git a/test/integration/app-dir-export/test/dynamicpage-prod.test.ts b/test/integration/app-dir-export/test/dynamicpage-prod.test.ts index 4a04638cd42c8..1729062aabfae 100644 --- a/test/integration/app-dir-export/test/dynamicpage-prod.test.ts +++ b/test/integration/app-dir-export/test/dynamicpage-prod.test.ts @@ -1,24 +1,21 @@ import { runTests } from './utils' describe('app dir - with output export - dynamic api route prod', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it.each([ - { dynamicPage: 'undefined' }, - { dynamicPage: "'error'" }, - { dynamicPage: "'force-static'" }, - { - dynamicPage: "'force-dynamic'", - expectedErrMsg: - 'Page with `dynamic = "force-dynamic"` couldn\'t be exported. `output: "export"` requires all pages be renderable statically', - }, - ])( - 'should work in prod with dynamicPage $dynamicPage', - async ({ dynamicPage, expectedErrMsg }) => { - await runTests({ isDev: false, dynamicPage, expectedErrMsg }) - } - ) - } - ) + describe('production mode', () => { + it.each([ + { dynamicPage: 'undefined' }, + { dynamicPage: "'error'" }, + { dynamicPage: "'force-static'" }, + { + dynamicPage: "'force-dynamic'", + expectedErrMsg: + 'Page with `dynamic = "force-dynamic"` couldn\'t be exported. `output: "export"` requires all pages be renderable statically', + }, + ])( + 'should work in prod with dynamicPage $dynamicPage', + async ({ dynamicPage, expectedErrMsg }) => { + await runTests({ isDev: false, dynamicPage, expectedErrMsg }) + } + ) + }) }) diff --git a/test/integration/app-dir-export/test/start.test.ts b/test/integration/app-dir-export/test/start.test.ts index 21545989c7c3a..1bdd07f1fade7 100644 --- a/test/integration/app-dir-export/test/start.test.ts +++ b/test/integration/app-dir-export/test/start.test.ts @@ -18,54 +18,47 @@ const nextConfig = new File(join(appDir, 'next.config.js')) let app describe('app dir - with output export (next start)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - afterEach(async () => { - await killApp(app) - nextConfig.restore() - await fs.remove(distDir) - await fs.remove(exportDir) - }) + describe('production mode', () => { + afterEach(async () => { + await killApp(app) + nextConfig.restore() + await fs.remove(distDir) + await fs.remove(exportDir) + }) - it('should error during next start with output export', async () => { - const { code } = await nextBuild(appDir) - expect(code).toBe(0) - const port = await findPort() - let stderr = '' - app = await nextStart(appDir, port, { - onStderr(msg: string) { - stderr += msg || '' - }, - }) - await check(() => stderr, /error/i) - expect(stderr).toContain( - '"next start" does not work with "output: export" configuration. Use "npx serve@latest out" instead.' - ) + it('should error during next start with output export', async () => { + const { code } = await nextBuild(appDir) + expect(code).toBe(0) + const port = await findPort() + let stderr = '' + app = await nextStart(appDir, port, { + onStderr(msg: string) { + stderr += msg || '' + }, }) + await check(() => stderr, /error/i) + expect(stderr).toContain( + '"next start" does not work with "output: export" configuration. Use "npx serve@latest out" instead.' + ) + }) - // TODO: Move this test to test/production to run in isolation. - ;(process.env.TURBOPACK_BUILD ? it.skip : it)( - 'should warn during next start with output standalone', - async () => { - nextConfig.replace(`output: 'export'`, `output: 'standalone'`) - const { code } = await nextBuild(appDir) - // eslint-disable-next-line jest/no-standalone-expect - expect(code).toBe(0) - const port = await findPort() - let stderr = '' - app = await nextStart(appDir, port, { - onStderr(msg: string) { - stderr += msg || '' - }, - }) - await check(() => stderr, /⚠/i) - // eslint-disable-next-line jest/no-standalone-expect - expect(stderr).toContain( - `"next start" does not work with "output: standalone" configuration. Use "node .next/standalone/server.js" instead.` - ) - } + it('should warn during next start with output standalone', async () => { + nextConfig.replace(`output: 'export'`, `output: 'standalone'`) + const { code } = await nextBuild(appDir) + // eslint-disable-next-line jest/no-standalone-expect + expect(code).toBe(0) + const port = await findPort() + let stderr = '' + app = await nextStart(appDir, port, { + onStderr(msg: string) { + stderr += msg || '' + }, + }) + await check(() => stderr, /⚠/i) + // eslint-disable-next-line jest/no-standalone-expect + expect(stderr).toContain( + `"next start" does not work with "output: standalone" configuration. Use "node .next/standalone/server.js" instead.` ) - } - ) + }) + }) }) diff --git a/test/integration/app-dir-export/test/trailing-slash-dev.test.ts b/test/integration/app-dir-export/test/trailing-slash-dev.test.ts index e0d8c6a3dc0aa..e60383fa10078 100644 --- a/test/integration/app-dir-export/test/trailing-slash-dev.test.ts +++ b/test/integration/app-dir-export/test/trailing-slash-dev.test.ts @@ -1,15 +1,12 @@ import { runTests } from './utils' describe('app dir - with output export - trailing slash dev', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it.each([{ trailingSlash: false }, { trailingSlash: true }])( - "should work in dev with trailingSlash '$trailingSlash'", - async ({ trailingSlash }) => { - await runTests({ isDev: true, trailingSlash }) - } - ) - } - ) + describe('development mode', () => { + it.each([{ trailingSlash: false }, { trailingSlash: true }])( + "should work in dev with trailingSlash '$trailingSlash'", + async ({ trailingSlash }) => { + await runTests({ isDev: true, trailingSlash }) + } + ) + }) }) diff --git a/test/integration/app-dir-export/test/trailing-slash-start.test.ts b/test/integration/app-dir-export/test/trailing-slash-start.test.ts index fc3964600e7af..9367c33fd1b3d 100644 --- a/test/integration/app-dir-export/test/trailing-slash-start.test.ts +++ b/test/integration/app-dir-export/test/trailing-slash-start.test.ts @@ -1,15 +1,12 @@ import { runTests } from './utils' describe('app dir - with output export - trailing slash prod', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it.each([{ trailingSlash: false }, { trailingSlash: true }])( - "should work in prod with trailingSlash '$trailingSlash'", - async ({ trailingSlash }) => { - await runTests({ isDev: false, trailingSlash }) - } - ) - } - ) + describe('production mode', () => { + it.each([{ trailingSlash: false }, { trailingSlash: true }])( + "should work in prod with trailingSlash '$trailingSlash'", + async ({ trailingSlash }) => { + await runTests({ isDev: false, trailingSlash }) + } + ) + }) }) diff --git a/test/integration/app-document-import-order/test/index.test.js b/test/integration/app-document-import-order/test/index.test.js index fabc297505e05..9786235ea4216 100644 --- a/test/integration/app-document-import-order/test/index.test.js +++ b/test/integration/app-document-import-order/test/index.test.js @@ -51,48 +51,14 @@ const respectsChunkAttachmentOrder = async () => { } describe('Root components import order', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - - // Test relies on webpack splitChunks overrides. - ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'Skipped in Turbopack', - () => { - it( - '_app chunks should be attached to de dom before page chunks', - respectsChunkAttachmentOrder - ) - } - ) - it( - 'root components should be imported in this order _document > _app > page in order to respect side effects', - respectsSideEffects - ) - } - ) -}) -;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { + describe('production mode', () => { beforeAll(async () => { + await nextBuild(appDir) appPort = await findPort() - app = await launchApp(join(__dirname, '../'), appPort) + app = await nextStart(appDir, appPort) }) - afterAll(() => killApp(app)) - it( - 'root components should be imported in this order _document > _app > page in order to respect side effects', - respectsSideEffects - ) - // Test relies on webpack splitChunks overrides. ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( 'Skipped in Turbopack', @@ -103,5 +69,33 @@ describe('Root components import order', () => { ) } ) - } -) + it( + 'root components should be imported in this order _document > _app > page in order to respect side effects', + respectsSideEffects + ) + }) +}) +describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(join(__dirname, '../'), appPort) + }) + + afterAll(() => killApp(app)) + + it( + 'root components should be imported in this order _document > _app > page in order to respect side effects', + respectsSideEffects + ) + + // Test relies on webpack splitChunks overrides. + ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'Skipped in Turbopack', + () => { + it( + '_app chunks should be attached to de dom before page chunks', + respectsChunkAttachmentOrder + ) + } + ) +}) diff --git a/test/integration/app-document-style-fragment/test/index.test.js b/test/integration/app-document-style-fragment/test/index.test.js index db6a60ef24393..80905dcd079b8 100644 --- a/test/integration/app-document-style-fragment/test/index.test.js +++ b/test/integration/app-document-style-fragment/test/index.test.js @@ -16,30 +16,27 @@ let server let app describe('Custom Document Fragment Styles', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - app = nextServer({ - dir: join(__dirname, '../'), - dev: false, - quiet: true, - }) - - server = await startApp(app) - appPort = server.address().port + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + app = nextServer({ + dir: join(__dirname, '../'), + dev: false, + quiet: true, }) - afterAll(() => stopApp(server)) - it('correctly adds styles from fragment styles key', async () => { - const html = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(html) + server = await startApp(app) + appPort = server.address().port + }) + afterAll(() => stopApp(server)) - const styles = $('style').text() - expect(styles).toMatch(/background:(.*|)hotpink/) - expect(styles).toMatch(/font-size:(.*|)16\.4px/) - }) - } - ) + it('correctly adds styles from fragment styles key', async () => { + const html = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(html) + + const styles = $('style').text() + expect(styles).toMatch(/background:(.*|)hotpink/) + expect(styles).toMatch(/font-size:(.*|)16\.4px/) + }) + }) }) diff --git a/test/integration/app-dynamic-error/test/index.test.ts b/test/integration/app-dynamic-error/test/index.test.ts index 6def977333c7a..eaf8901df6bcd 100644 --- a/test/integration/app-dynamic-error/test/index.test.ts +++ b/test/integration/app-dynamic-error/test/index.test.ts @@ -1,20 +1,17 @@ import { nextBuild } from 'next-test-utils' import { join } from 'path' describe('app-dynamic-error', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('throws an error when prerendering a page with config dynamic error', async () => { - const appDir = join(__dirname, '../../app-dynamic-error') - const { stderr, code } = await nextBuild(appDir, [], { - stderr: true, - stdout: true, - }) - expect(stderr).toContain( - 'Error occurred prerendering page "/dynamic-error"' - ) - expect(code).toBe(1) + describe('production mode', () => { + it('throws an error when prerendering a page with config dynamic error', async () => { + const appDir = join(__dirname, '../../app-dynamic-error') + const { stderr, code } = await nextBuild(appDir, [], { + stderr: true, + stdout: true, }) - } - ) + expect(stderr).toContain( + 'Error occurred prerendering page "/dynamic-error"' + ) + expect(code).toBe(1) + }) + }) }) diff --git a/test/integration/app-tree/test/index.test.js b/test/integration/app-tree/test/index.test.js index 909c14e8224b1..b70cd5556d2ec 100644 --- a/test/integration/app-tree/test/index.test.js +++ b/test/integration/app-tree/test/index.test.js @@ -52,27 +52,21 @@ const runTests = () => { } describe('AppTree', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(() => killApp(app)) - runTests() - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - runTests() - } - ) + describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + runTests() + }) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + runTests() + }) }) diff --git a/test/integration/auto-export-error-bail/test/index.test.js b/test/integration/auto-export-error-bail/test/index.test.js index f9d8c13369e4d..9537f15453cf9 100644 --- a/test/integration/auto-export-error-bail/test/index.test.js +++ b/test/integration/auto-export-error-bail/test/index.test.js @@ -30,10 +30,7 @@ const runTests = () => { } describe('Auto Export _error bail', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - runTests() - } - ) + describe('production mode', () => { + runTests() + }) }) diff --git a/test/integration/auto-export-query-error/test/index.test.js b/test/integration/auto-export-query-error/test/index.test.js index dd10d248c5f81..e97b95beea341 100644 --- a/test/integration/auto-export-query-error/test/index.test.js +++ b/test/integration/auto-export-query-error/test/index.test.js @@ -21,22 +21,15 @@ const runTests = () => { } describe('Auto Export', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - const { stderr: curStderr, code: curCode } = await nextBuild( - appDir, - [], - { - stderr: true, - } - ) - stderr = curStderr - exitCode = curCode + describe('production mode', () => { + beforeAll(async () => { + const { stderr: curStderr, code: curCode } = await nextBuild(appDir, [], { + stderr: true, }) + stderr = curStderr + exitCode = curCode + }) - runTests() - } - ) + runTests() + }) }) diff --git a/test/integration/auto-export/test/index.test.js b/test/integration/auto-export/test/index.test.js index 7113b4c9eae46..87cd1e674b08c 100644 --- a/test/integration/auto-export/test/index.test.js +++ b/test/integration/auto-export/test/index.test.js @@ -57,22 +57,19 @@ const runTests = () => { } describe('Auto Export', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - runTests() - } - ) + runTests() + }) describe('dev', () => { beforeAll(async () => { diff --git a/test/integration/basepath-root-catch-all/test/index.test.js b/test/integration/basepath-root-catch-all/test/index.test.js index 549cb68ecf308..c14586759fbd0 100644 --- a/test/integration/basepath-root-catch-all/test/index.test.js +++ b/test/integration/basepath-root-catch-all/test/index.test.js @@ -42,16 +42,13 @@ const runTests = () => { runTests() } ) -;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - runTests() - } -) +describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + runTests() +}) diff --git a/test/integration/bigint/test/index.test.js b/test/integration/bigint/test/index.test.js index 6924b2779fc8e..099241bf42251 100644 --- a/test/integration/bigint/test/index.test.js +++ b/test/integration/bigint/test/index.test.js @@ -33,30 +33,24 @@ const runTests = () => { } describe('bigint API route support', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(() => killApp(app)) + describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests() - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await fs.remove(nextConfig) - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) + runTests() + }) + describe('production mode', () => { + beforeAll(async () => { + await fs.remove(nextConfig) + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) - runTests() - } - ) + runTests() + }) }) diff --git a/test/integration/build-output/test/index.test.js b/test/integration/build-output/test/index.test.js index 774368921d7a7..a99e3b02c41e4 100644 --- a/test/integration/build-output/test/index.test.js +++ b/test/integration/build-output/test/index.test.js @@ -10,192 +10,215 @@ const fixturesDir = join(__dirname, '..', 'fixtures') const nextConfig = new File(join(fixturesDir, 'basic-app/next.config.js')) describe('Build Output', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const configs = [{}, { gzipSize: false }] - - for (const experimental of configs) { - describe(`Basic Application Output (experimental: ${JSON.stringify( - experimental - )})`, () => { - let stdout - const appDir = join(fixturesDir, 'basic-app') - - const hasExperimentalConfig = Object.keys(experimental).length > 0 - - beforeAll(async () => { - await remove(join(appDir, '.next')) - if (hasExperimentalConfig) { - nextConfig.write( - `module.exports = { experimental: ${JSON.stringify( - experimental - )} };` - ) - } - ;({ stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - }) + describe('production mode', () => { + const configs = [{}, { gzipSize: false }] + for (const experimental of configs) { + describe(`Basic Application Output (experimental: ${JSON.stringify( + experimental + )})`, () => { + let stdout + const appDir = join(fixturesDir, 'basic-app') + + const hasExperimentalConfig = Object.keys(experimental).length > 0 + + beforeAll(async () => { + await remove(join(appDir, '.next')) if (hasExperimentalConfig) { - afterAll(async () => { - nextConfig.delete() - }) + nextConfig.write( + `module.exports = { experimental: ${JSON.stringify( + experimental + )} };` + ) } + ;({ stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + }) - it('should not include internal pages', async () => { - expect(stdout).toMatch(/\/ (.* )?\d{1,} k?B/) - expect(stdout).toMatch(/\+ First Load JS shared by all [ 0-9.]* kB/) - expect(stdout).toMatch(/ chunks\/.*\.js [ 0-9.]* kB/) - expect(stdout).toMatch(/ chunks\/.*\.js [ 0-9. ]* kB/) + if (hasExperimentalConfig) { + afterAll(async () => { + nextConfig.delete() + }) + } - expect(stdout).not.toContain(' /_document') - expect(stdout).not.toContain(' /_app') - expect(stdout).not.toContain(' /_error') - expect(stdout).not.toContain('') + it('should not include internal pages', async () => { + expect(stdout).toMatch(/\/ (.* )?\d{1,} k?B/) + expect(stdout).toMatch(/\+ First Load JS shared by all [ 0-9.]* kB/) + expect(stdout).toMatch(/ chunks\/.*\.js [ 0-9.]* kB/) + expect(stdout).toMatch(/ chunks\/.*\.js [ 0-9. ]* kB/) - expect(stdout).toContain('○ /') - }) + expect(stdout).not.toContain(' /_document') + expect(stdout).not.toContain(' /_app') + expect(stdout).not.toContain(' /_error') + expect(stdout).not.toContain('') - // TODO: change format of this test to be more reliable - it.skip('should not deviate from snapshot', async () => { - console.log(stdout) + expect(stdout).toContain('○ /') + }) - if (process.env.NEXT_PRIVATE_SKIP_SIZE_TESTS) { - return - } + // TODO: change format of this test to be more reliable + it.skip('should not deviate from snapshot', async () => { + console.log(stdout) - const parsePageSize = (page) => - stdout.match( - new RegExp(` ${page} .*?((?:\\d|\\.){1,} (?:\\w{1,})) `) - )[1] - - const parsePageFirstLoad = (page) => - stdout.match( - new RegExp( - ` ${page} .*?(?:(?:\\d|\\.){1,}) .*? ((?:\\d|\\.){1,} (?:\\w{1,}))` - ) - )[1] - - const parseSharedSize = (sharedPartName) => { - const matches = stdout.match( - new RegExp( - `${sharedPartName} .*? ((?:\\d|\\.){1,} (?:\\w{1,}))` - ) + if (process.env.NEXT_PRIVATE_SKIP_SIZE_TESTS) { + return + } + + const parsePageSize = (page) => + stdout.match( + new RegExp(` ${page} .*?((?:\\d|\\.){1,} (?:\\w{1,})) `) + )[1] + + const parsePageFirstLoad = (page) => + stdout.match( + new RegExp( + ` ${page} .*?(?:(?:\\d|\\.){1,}) .*? ((?:\\d|\\.){1,} (?:\\w{1,}))` ) + )[1] - if (!matches) { - throw new Error(`Could not match ${sharedPartName}`) - } + const parseSharedSize = (sharedPartName) => { + const matches = stdout.match( + new RegExp(`${sharedPartName} .*? ((?:\\d|\\.){1,} (?:\\w{1,}))`) + ) - return matches[1] + if (!matches) { + throw new Error(`Could not match ${sharedPartName}`) } - const indexSize = parsePageSize('/') - const indexFirstLoad = parsePageFirstLoad('/') - - const err404Size = parsePageSize('/404') - const err404FirstLoad = parsePageFirstLoad('/404') - - const sharedByAll = parseSharedSize('shared by all') - const _appSize = parseSharedSize('_app-.*?\\.js') - const webpackSize = parseSharedSize('webpack-.*?\\.js') - const mainSize = parseSharedSize('main-.*?\\.js') - const frameworkSize = parseSharedSize('framework-.*?\\.js') - - for (const size of [ - indexSize, - indexFirstLoad, - err404Size, - err404FirstLoad, - sharedByAll, - _appSize, - webpackSize, - mainSize, - frameworkSize, - ]) { - expect(parseFloat(size)).toBeGreaterThan(0) - } + return matches[1] + } - // const gz = experimental.gzipSize !== false + const indexSize = parsePageSize('/') + const indexFirstLoad = parsePageFirstLoad('/') + + const err404Size = parsePageSize('/404') + const err404FirstLoad = parsePageFirstLoad('/404') + + const sharedByAll = parseSharedSize('shared by all') + const _appSize = parseSharedSize('_app-.*?\\.js') + const webpackSize = parseSharedSize('webpack-.*?\\.js') + const mainSize = parseSharedSize('main-.*?\\.js') + const frameworkSize = parseSharedSize('framework-.*?\\.js') + + for (const size of [ + indexSize, + indexFirstLoad, + err404Size, + err404FirstLoad, + sharedByAll, + _appSize, + webpackSize, + mainSize, + frameworkSize, + ]) { + expect(parseFloat(size)).toBeGreaterThan(0) + } - // expect(parseFloat(indexSize) / 1000).toBeCloseTo( - // gz ? 0.251 : 0.394, - // 2 - // ) - expect(indexSize.endsWith('B')).toBe(true) + // const gz = experimental.gzipSize !== false - // expect(parseFloat(indexFirstLoad)).toBeCloseTo(gz ? 64 : 196, 1) - expect(indexFirstLoad.endsWith('kB')).toBe(true) + // expect(parseFloat(indexSize) / 1000).toBeCloseTo( + // gz ? 0.251 : 0.394, + // 2 + // ) + expect(indexSize.endsWith('B')).toBe(true) - // expect(parseFloat(err404Size)).toBeCloseTo(gz ? 3.17 : 8.51, 1) - expect(err404Size.endsWith('B')).toBe(true) + // expect(parseFloat(indexFirstLoad)).toBeCloseTo(gz ? 64 : 196, 1) + expect(indexFirstLoad.endsWith('kB')).toBe(true) - // expect(parseFloat(err404FirstLoad)).toBeCloseTo(gz ? 66.9 : 204, 1) - expect(err404FirstLoad.endsWith('kB')).toBe(true) + // expect(parseFloat(err404Size)).toBeCloseTo(gz ? 3.17 : 8.51, 1) + expect(err404Size.endsWith('B')).toBe(true) - // expect(parseFloat(sharedByAll)).toBeCloseTo(gz ? 63.7 : 196, 1) - expect(sharedByAll.endsWith('kB')).toBe(true) + // expect(parseFloat(err404FirstLoad)).toBeCloseTo(gz ? 66.9 : 204, 1) + expect(err404FirstLoad.endsWith('kB')).toBe(true) - // const appSizeValue = _appSize.endsWith('kB') - // ? parseFloat(_appSize) - // : parseFloat(_appSize) / 1000 - // expect(appSizeValue).toBeCloseTo(gz ? 0.799 : 1.63, 1) - expect(_appSize.endsWith('kB') || _appSize.endsWith(' B')).toBe( - true - ) + // expect(parseFloat(sharedByAll)).toBeCloseTo(gz ? 63.7 : 196, 1) + expect(sharedByAll.endsWith('kB')).toBe(true) - // const webpackSizeValue = webpackSize.endsWith('kB') - // ? parseFloat(webpackSize) - // : parseFloat(webpackSize) / 1000 - // expect(webpackSizeValue).toBeCloseTo(gz ? 0.766 : 1.46, 2) - expect( - webpackSize.endsWith('kB') || webpackSize.endsWith(' B') - ).toBe(true) + // const appSizeValue = _appSize.endsWith('kB') + // ? parseFloat(_appSize) + // : parseFloat(_appSize) / 1000 + // expect(appSizeValue).toBeCloseTo(gz ? 0.799 : 1.63, 1) + expect(_appSize.endsWith('kB') || _appSize.endsWith(' B')).toBe(true) - // expect(parseFloat(mainSize)).toBeCloseTo(gz ? 20.1 : 62.7, 1) - expect(mainSize.endsWith('kB')).toBe(true) + // const webpackSizeValue = webpackSize.endsWith('kB') + // ? parseFloat(webpackSize) + // : parseFloat(webpackSize) / 1000 + // expect(webpackSizeValue).toBeCloseTo(gz ? 0.766 : 1.46, 2) + expect(webpackSize.endsWith('kB') || webpackSize.endsWith(' B')).toBe( + true + ) - // expect(parseFloat(frameworkSize)).toBeCloseTo(gz ? 42.0 : 130, 1) - expect(frameworkSize.endsWith('kB')).toBe(true) - }) + // expect(parseFloat(mainSize)).toBeCloseTo(gz ? 20.1 : 62.7, 1) + expect(mainSize.endsWith('kB')).toBe(true) - it('should print duration when rendering or get static props takes long', () => { - const matches = stdout.match( - / \/slow-static\/.+\/.+(?: \(\d+ ms\))?| \[\+\d+ more paths\]/g - ) + // expect(parseFloat(frameworkSize)).toBeCloseTo(gz ? 42.0 : 130, 1) + expect(frameworkSize.endsWith('kB')).toBe(true) + }) - for (const check of [ - // summary - expect.stringMatching( - /\/\[propsDuration\]\/\[renderDuration\] \(\d+ ms\)/ - ), - // ordered by duration, includes duration - expect.stringMatching(/\/2000\/10 \(\d+ ms\)$/), - expect.stringMatching(/\/10\/1000 \(\d+ ms\)$/), - expect.stringMatching(/\/300\/10 \(\d+ ms\)$/), - // max of 7 preview paths - ' [+2 more paths]', - ]) { - // the order isn't guaranteed on the timing tests as while() is being - // used in the render so can block the thread of other renders sharing - // the same worker - expect(matches).toContainEqual(check) - } - }) + it('should print duration when rendering or get static props takes long', () => { + const matches = stdout.match( + / \/slow-static\/.+\/.+(?: \(\d+ ms\))?| \[\+\d+ more paths\]/g + ) + + for (const check of [ + // summary + expect.stringMatching( + /\/\[propsDuration\]\/\[renderDuration\] \(\d+ ms\)/ + ), + // ordered by duration, includes duration + expect.stringMatching(/\/2000\/10 \(\d+ ms\)$/), + expect.stringMatching(/\/10\/1000 \(\d+ ms\)$/), + expect.stringMatching(/\/300\/10 \(\d+ ms\)$/), + // max of 7 preview paths + ' [+2 more paths]', + ]) { + // the order isn't guaranteed on the timing tests as while() is being + // used in the render so can block the thread of other renders sharing + // the same worker + expect(matches).toContainEqual(check) + } + }) - it('should not emit extracted comments', async () => { - const files = await recursiveReadDir(join(appDir, '.next'), { - pathnameFilter: (f) => /\.txt|\.LICENSE\./.test(f), - }) - expect(files).toEqual([]) + it('should not emit extracted comments', async () => { + const files = await recursiveReadDir(join(appDir, '.next'), { + pathnameFilter: (f) => /\.txt|\.LICENSE\./.test(f), }) + expect(files).toEqual([]) }) - } + }) + } + + describe('Custom App Output', () => { + const appDir = join(fixturesDir, 'with-app') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + it('should not include custom error', async () => { + const { stdout } = await nextBuild(appDir, [], { + stdout: true, + }) + + expect(stdout).toMatch(/\/ (.* )?\d{1,} k?B/) + expect(stdout).toMatch(/\/_app (.* )?\d{1,} k?B/) + expect(stdout).toMatch(/\+ First Load JS shared by all \s*[0-9.]+ kB/) + expect(stdout).toMatch(/ chunks\/.*\.js \s*[0-9.]+ kB/) + + expect(stdout).not.toContain(' /_document') + expect(stdout).not.toContain(' /_error') + expect(stdout).not.toContain('') - describe('Custom App Output', () => { - const appDir = join(fixturesDir, 'with-app') + expect(stdout).toContain(' /_app') + expect(stdout).toContain('○ /') + }) + }) + + // AMP is not supported with Turbopack. + ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'With AMP Output', + () => { + const appDir = join(fixturesDir, 'with-amp') beforeAll(async () => { await remove(join(appDir, '.next')) @@ -206,8 +229,9 @@ describe('Build Output', () => { stdout: true, }) - expect(stdout).toMatch(/\/ (.* )?\d{1,} k?B/) - expect(stdout).toMatch(/\/_app (.* )?\d{1,} k?B/) + expect(stdout).toMatch(/\/ (.* )?[0-9.]+ k?B \s*[0-9.]+ kB/) + expect(stdout).toMatch(/\/amp (.* )?AMP/) + expect(stdout).toMatch(/\/hybrid (.* )?[0-9.]+ k?B/) expect(stdout).toMatch(/\+ First Load JS shared by all \s*[0-9.]+ kB/) expect(stdout).toMatch(/ chunks\/.*\.js \s*[0-9.]+ kB/) @@ -215,97 +239,64 @@ describe('Build Output', () => { expect(stdout).not.toContain(' /_error') expect(stdout).not.toContain('') - expect(stdout).toContain(' /_app') expect(stdout).toContain('○ /') }) - }) - - // AMP is not supported with Turbopack. - ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'With AMP Output', - () => { - const appDir = join(fixturesDir, 'with-amp') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - - it('should not include custom error', async () => { - const { stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - - expect(stdout).toMatch(/\/ (.* )?[0-9.]+ k?B \s*[0-9.]+ kB/) - expect(stdout).toMatch(/\/amp (.* )?AMP/) - expect(stdout).toMatch(/\/hybrid (.* )?[0-9.]+ k?B/) - expect(stdout).toMatch( - /\+ First Load JS shared by all \s*[0-9.]+ kB/ - ) - expect(stdout).toMatch(/ chunks\/.*\.js \s*[0-9.]+ kB/) - - expect(stdout).not.toContain(' /_document') - expect(stdout).not.toContain(' /_error') - expect(stdout).not.toContain('') + } + ) - expect(stdout).toContain('○ /') - }) - } - ) + describe('Custom Error Output', () => { + const appDir = join(fixturesDir, 'with-error') - describe('Custom Error Output', () => { - const appDir = join(fixturesDir, 'with-error') + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) + it('should not include custom app', async () => { + const { stdout } = await nextBuild(appDir, [], { + stdout: true, }) - it('should not include custom app', async () => { - const { stdout } = await nextBuild(appDir, [], { - stdout: true, - }) + expect(stdout).toMatch(/\/ (.* )?\d{1,} k?B/) + expect(stdout).toMatch(/ƒ \/404 (.* )?\d{1,} k?B/) + expect(stdout).toMatch(/\+ First Load JS shared by all [ 0-9.]* kB/) + expect(stdout).toMatch(/ chunks\/.*\.js [ 0-9.]* kB/) - expect(stdout).toMatch(/\/ (.* )?\d{1,} k?B/) - expect(stdout).toMatch(/ƒ \/404 (.* )?\d{1,} k?B/) - expect(stdout).toMatch(/\+ First Load JS shared by all [ 0-9.]* kB/) - expect(stdout).toMatch(/ chunks\/.*\.js [ 0-9.]* kB/) - - expect(stdout).not.toContain(' /_document') - expect(stdout).not.toContain(' /_app') - expect(stdout).not.toContain('') + expect(stdout).not.toContain(' /_document') + expect(stdout).not.toContain(' /_app') + expect(stdout).not.toContain('') - expect(stdout).not.toContain(' /_error') - expect(stdout).toContain('○ /') - }) + expect(stdout).not.toContain(' /_error') + expect(stdout).toContain('○ /') }) + }) - describe('Custom Static Error Output', () => { - const appDir = join(fixturesDir, 'with-error-static') + describe('Custom Static Error Output', () => { + const appDir = join(fixturesDir, 'with-error-static') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should not specify /404 as lambda when static', async () => { - const { stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - expect(stdout).toContain('○ /404') - expect(stdout).not.toContain('ƒ /_error') - expect(stdout).not.toContain('') + it('should not specify /404 as lambda when static', async () => { + const { stdout } = await nextBuild(appDir, [], { + stdout: true, }) + expect(stdout).toContain('○ /404') + expect(stdout).not.toContain('ƒ /_error') + expect(stdout).not.toContain('') }) + }) - describe('With Parallel Routes', () => { - it('should not have duplicate paths that resolve to the same route', async () => { - const appDir = join(fixturesDir, 'with-parallel-routes') + describe('With Parallel Routes', () => { + it('should not have duplicate paths that resolve to the same route', async () => { + const appDir = join(fixturesDir, 'with-parallel-routes') - const { stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - - expect(stdout.match(/○ \/root-page /g).length).toBe(1) + const { stdout } = await nextBuild(appDir, [], { + stdout: true, }) + + expect(stdout.match(/○ \/root-page /g).length).toBe(1) }) - } - ) + }) + }) }) diff --git a/test/integration/build-trace-extra-entries-monorepo/test/index.test.ts b/test/integration/build-trace-extra-entries-monorepo/test/index.test.ts index 53ede30984bc6..24b611b1f06ca 100644 --- a/test/integration/build-trace-extra-entries-monorepo/test/index.test.ts +++ b/test/integration/build-trace-extra-entries-monorepo/test/index.test.ts @@ -7,27 +7,24 @@ import { nextBuild } from 'next-test-utils' const appDir = join(__dirname, '../app') describe('build trace with extra entries in monorepo', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should build and trace correctly', async () => { - const result = await nextBuild(appDir, undefined, { - cwd: appDir, - stderr: true, - stdout: true, - }) - expect(result.code).toBe(0) - console.log(result.stderr) - console.log(result.stdout) + describe('production mode', () => { + it('should build and trace correctly', async () => { + const result = await nextBuild(appDir, undefined, { + cwd: appDir, + stderr: true, + stdout: true, + }) + expect(result.code).toBe(0) + console.log(result.stderr) + console.log(result.stdout) - const appDirRoute1Trace = await fs.readJSON( - join(appDir, '.next/server/app/route1/route.js.nft.json') - ) + const appDirRoute1Trace = await fs.readJSON( + join(appDir, '.next/server/app/route1/route.js.nft.json') + ) - expect(appDirRoute1Trace.files).toContain( - '../../../../../other/included.txt' - ) - }) - } - ) + expect(appDirRoute1Trace.files).toContain( + '../../../../../other/included.txt' + ) + }) + }) }) diff --git a/test/integration/build-trace-extra-entries-turbo/test/index.test.js b/test/integration/build-trace-extra-entries-turbo/test/index.test.js index 0d488b2837d44..415d11eb02b07 100644 --- a/test/integration/build-trace-extra-entries-turbo/test/index.test.js +++ b/test/integration/build-trace-extra-entries-turbo/test/index.test.js @@ -7,97 +7,94 @@ import { nextBuild } from 'next-test-utils' const appDir = join(__dirname, '../app') describe('build trace with extra entries', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should build and trace correctly', async () => { - const result = await nextBuild(appDir, undefined, { - cwd: appDir, - stderr: true, - stdout: true, - }) - console.log(result) - expect(result.code).toBe(0) + describe('production mode', () => { + it('should build and trace correctly', async () => { + const result = await nextBuild(appDir, undefined, { + cwd: appDir, + stderr: true, + stdout: true, + }) + console.log(result) + expect(result.code).toBe(0) - const appTrace = await fs.readJSON( - join(appDir, '.next/server/pages/_app.js.nft.json') - ) - const indexTrace = await fs.readJSON( - join(appDir, '.next/server/pages/index.js.nft.json') - ) - const anotherTrace = await fs.readJSON( - join(appDir, '.next/server/pages/another.js.nft.json') - ) - const imageTrace = await fs.readJSON( - join(appDir, '.next/server/pages/image-import.js.nft.json') + const appTrace = await fs.readJSON( + join(appDir, '.next/server/pages/_app.js.nft.json') + ) + const indexTrace = await fs.readJSON( + join(appDir, '.next/server/pages/index.js.nft.json') + ) + const anotherTrace = await fs.readJSON( + join(appDir, '.next/server/pages/another.js.nft.json') + ) + const imageTrace = await fs.readJSON( + join(appDir, '.next/server/pages/image-import.js.nft.json') + ) + const appDirRoute1Trace = await fs.readJSON( + join(appDir, '.next/server/app/route1/route.js.nft.json') + ) + + expect( + appDirRoute1Trace.files.some( + (file) => file === '../../../../include-me/hello.txt' ) - const appDirRoute1Trace = await fs.readJSON( - join(appDir, '.next/server/app/route1/route.js.nft.json') + ).toBe(true) + expect( + appDirRoute1Trace.files.some( + (file) => file === '../../../../include-me/second.txt' ) + ).toBe(true) + expect( + appDirRoute1Trace.files.some((file) => file.includes('exclude-me')) + ).toBe(false) - expect( - appDirRoute1Trace.files.some( - (file) => file === '../../../../include-me/hello.txt' - ) - ).toBe(true) - expect( - appDirRoute1Trace.files.some( - (file) => file === '../../../../include-me/second.txt' - ) - ).toBe(true) - expect( - appDirRoute1Trace.files.some((file) => file.includes('exclude-me')) - ).toBe(false) - - const tracedFiles = [ - ...appTrace.files, - ...indexTrace.files, - ...anotherTrace.files, - ...imageTrace.files, - ] + const tracedFiles = [ + ...appTrace.files, + ...indexTrace.files, + ...anotherTrace.files, + ...imageTrace.files, + ] - // Skip hello.json check for Turbopack as it doesn't support webpack entry modifications - if (!process.env.TURBOPACK_BUILD) { - expect(tracedFiles.some((file) => file.endsWith('hello.json'))).toBe( - true - ) - } + // Skip hello.json check for Turbopack as it doesn't support webpack entry modifications + if (!process.env.TURBOPACK_BUILD) { + expect(tracedFiles.some((file) => file.endsWith('hello.json'))).toBe( + true + ) + } - expect( - tracedFiles.some((file) => file.includes('some-cms/index.js')) - ).toBe(true) - expect( - tracedFiles.some((file) => file === '../../../include-me/hello.txt') - ).toBe(true) - expect( - tracedFiles.some((file) => file === '../../../include-me/second.txt') - ).toBe(true) - expect( - indexTrace.files.some((file) => file.includes('exclude-me')) - ).toBe(false) + expect( + tracedFiles.some((file) => file.includes('some-cms/index.js')) + ).toBe(true) + expect( + tracedFiles.some((file) => file === '../../../include-me/hello.txt') + ).toBe(true) + expect( + tracedFiles.some((file) => file === '../../../include-me/second.txt') + ).toBe(true) + expect(indexTrace.files.some((file) => file.includes('exclude-me'))).toBe( + false + ) - expect( - tracedFiles.some((file) => - file.includes('nested-structure/constants/package.json') - ) - ).toBe(true) - expect( - tracedFiles.some((file) => - file.includes('nested-structure/package.json') - ) - ).toBe(true) - expect( - tracedFiles.some((file) => - file.includes('nested-structure/dist/constants.js') - ) - ).toBe(true) - expect( - tracedFiles.some((file) => file.includes('public/another.jpg')) - ).toBe(true) - expect( - tracedFiles.some((file) => file.includes('public/test.jpg')) - ).toBe(false) - }) - } - ) + expect( + tracedFiles.some((file) => + file.includes('nested-structure/constants/package.json') + ) + ).toBe(true) + expect( + tracedFiles.some((file) => + file.includes('nested-structure/package.json') + ) + ).toBe(true) + expect( + tracedFiles.some((file) => + file.includes('nested-structure/dist/constants.js') + ) + ).toBe(true) + expect( + tracedFiles.some((file) => file.includes('public/another.jpg')) + ).toBe(true) + expect(tracedFiles.some((file) => file.includes('public/test.jpg'))).toBe( + false + ) + }) + }) }) diff --git a/test/integration/build-trace-extra-entries/test/index.test.js b/test/integration/build-trace-extra-entries/test/index.test.js index 53beaec5c5c33..8071403c3c3b4 100644 --- a/test/integration/build-trace-extra-entries/test/index.test.js +++ b/test/integration/build-trace-extra-entries/test/index.test.js @@ -7,149 +7,144 @@ import { nextBuild } from 'next-test-utils' const appDir = join(__dirname, '../app') describe('build trace with extra entries', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should build and trace correctly', async () => { - const result = await nextBuild(appDir, undefined, { - cwd: appDir, - stderr: true, - stdout: true, - }) - expect(result.code).toBe(0) + describe('production mode', () => { + it('should build and trace correctly', async () => { + const result = await nextBuild(appDir, undefined, { + cwd: appDir, + stderr: true, + stdout: true, + }) + expect(result.code).toBe(0) + + const appTrace = await fs.readJSON( + join(appDir, '.next/server/pages/_app.js.nft.json') + ) + const indexTrace = await fs.readJSON( + join(appDir, '.next/server/pages/index.js.nft.json') + ) + const anotherTrace = await fs.readJSON( + join(appDir, '.next/server/pages/another.js.nft.json') + ) + const imageTrace = await fs.readJSON( + join(appDir, '.next/server/pages/image-import.js.nft.json') + ) + const appDirRoute1Trace = await fs.readJSON( + join(appDir, '.next/server/app/route1/route.js.nft.json') + ) - const appTrace = await fs.readJSON( - join(appDir, '.next/server/pages/_app.js.nft.json') + expect(appDirRoute1Trace.files).toContain( + '../../../../include-me/hello.txt' + ) + expect(appDirRoute1Trace.files).toContain( + '../../../../include-me/second.txt' + ) + expect( + appDirRoute1Trace.files.some( + (file) => file === '../../../../include-me-global.txt' ) - const indexTrace = await fs.readJSON( - join(appDir, '.next/server/pages/index.js.nft.json') + ).toBe(true) + expect( + appDirRoute1Trace.files.some((file) => file.includes('exclude-me')) + ).toBe(false) + expect(appDirRoute1Trace.files).toEqual( + expect.arrayContaining([ + '../../../../node_modules/pkg-behind-symlink/index.js', + '../../../../node_modules/pkg-behind-symlink/package.json', + ]) + ) + // This assertion not really needed, but ensures consistency between Turbopack and Webpack + expect( + appDirRoute1Trace.files.some((file) => + file.startsWith('../../../../node_modules/pkg/') ) - const anotherTrace = await fs.readJSON( - join(appDir, '.next/server/pages/another.js.nft.json') + ).toBe(false) + + expect( + indexTrace.files.filter( + (file) => file.includes('chunks') && file.endsWith('.js') + ).length + ).toBeGreaterThan( + anotherTrace.files.filter( + (file) => file.includes('chunks') && file.endsWith('.js') + ).length + ) + + // Skip hello.json check for Turbopack as it doesn't support webpack entry modifications + if (!process.env.TURBOPACK_BUILD) { + expect(appTrace.files.some((file) => file.endsWith('hello.json'))).toBe( + true ) - const imageTrace = await fs.readJSON( - join(appDir, '.next/server/pages/image-import.js.nft.json') + } + // Skip lib/get-data.js check for Turbopack as it doesn't support webpack entry modifications + if (!process.env.TURBOPACK_BUILD) { + expect( + appTrace.files.some((file) => file.endsWith('lib/get-data.js')) + ).toBe(true) + } + expect( + appTrace.files.some((file) => file === '../../../include-me-global.txt') + ).toBe(true) + + expect( + indexTrace.files.some((file) => file.endsWith('hello.json')) + ).toBeFalsy() + expect( + indexTrace.files.some((file) => file.endsWith('some-dir')) + ).toBeFalsy() + expect( + indexTrace.files.some((file) => + file.endsWith('.dot-folder/another-file.txt') ) - const appDirRoute1Trace = await fs.readJSON( - join(appDir, '.next/server/app/route1/route.js.nft.json') + ).toBe(true) + expect( + indexTrace.files.some((file) => file.endsWith('some-dir/file.txt')) + ).toBe(true) + expect( + indexTrace.files.some((file) => file.includes('some-cms/index.js')) + ).toBe(true) + expect(indexTrace.files).toContain('../../../include-me/hello.txt') + expect(indexTrace.files).toContain('../../../include-me/second.txt') + expect(indexTrace.files.some((file) => file.includes('exclude-me'))).toBe( + false + ) + expect( + indexTrace.files.some( + (file) => file === '../../../include-me-global.txt' ) + ).toBe(true) - expect(appDirRoute1Trace.files).toContain( - '../../../../include-me/hello.txt' + expect( + anotherTrace.files.some((file) => + file.includes('nested-structure/constants/package.json') ) - expect(appDirRoute1Trace.files).toContain( - '../../../../include-me/second.txt' + ).toBe(true) + expect( + anotherTrace.files.some((file) => + file.includes('nested-structure/package.json') ) - expect( - appDirRoute1Trace.files.some( - (file) => file === '../../../../include-me-global.txt' - ) - ).toBe(true) - expect( - appDirRoute1Trace.files.some((file) => file.includes('exclude-me')) - ).toBe(false) - expect(appDirRoute1Trace.files).toEqual( - expect.arrayContaining([ - '../../../../node_modules/pkg-behind-symlink/index.js', - '../../../../node_modules/pkg-behind-symlink/package.json', - ]) + ).toBe(true) + expect( + anotherTrace.files.some((file) => + file.includes('nested-structure/dist/constants.js') ) - // This assertion not really needed, but ensures consistency between Turbopack and Webpack - expect( - appDirRoute1Trace.files.some((file) => - file.startsWith('../../../../node_modules/pkg/') - ) - ).toBe(false) - - expect( - indexTrace.files.filter( - (file) => file.includes('chunks') && file.endsWith('.js') - ).length - ).toBeGreaterThan( - anotherTrace.files.filter( - (file) => file.includes('chunks') && file.endsWith('.js') - ).length + ).toBe(true) + expect( + anotherTrace.files.some( + (file) => file === '../../../include-me-global.txt' ) + ).toBe(true) - // Skip hello.json check for Turbopack as it doesn't support webpack entry modifications - if (!process.env.TURBOPACK_BUILD) { - expect( - appTrace.files.some((file) => file.endsWith('hello.json')) - ).toBe(true) - } - // Skip lib/get-data.js check for Turbopack as it doesn't support webpack entry modifications - if (!process.env.TURBOPACK_BUILD) { - expect( - appTrace.files.some((file) => file.endsWith('lib/get-data.js')) - ).toBe(true) - } - expect( - appTrace.files.some( - (file) => file === '../../../include-me-global.txt' - ) - ).toBe(true) - - expect( - indexTrace.files.some((file) => file.endsWith('hello.json')) - ).toBeFalsy() - expect( - indexTrace.files.some((file) => file.endsWith('some-dir')) - ).toBeFalsy() - expect( - indexTrace.files.some((file) => - file.endsWith('.dot-folder/another-file.txt') - ) - ).toBe(true) - expect( - indexTrace.files.some((file) => file.endsWith('some-dir/file.txt')) - ).toBe(true) - expect( - indexTrace.files.some((file) => file.includes('some-cms/index.js')) - ).toBe(true) - expect(indexTrace.files).toContain('../../../include-me/hello.txt') - expect(indexTrace.files).toContain('../../../include-me/second.txt') - expect( - indexTrace.files.some((file) => file.includes('exclude-me')) - ).toBe(false) - expect( - indexTrace.files.some( - (file) => file === '../../../include-me-global.txt' - ) - ).toBe(true) - - expect( - anotherTrace.files.some((file) => - file.includes('nested-structure/constants/package.json') - ) - ).toBe(true) - expect( - anotherTrace.files.some((file) => - file.includes('nested-structure/package.json') - ) - ).toBe(true) - expect( - anotherTrace.files.some((file) => - file.includes('nested-structure/dist/constants.js') - ) - ).toBe(true) - expect( - anotherTrace.files.some( - (file) => file === '../../../include-me-global.txt' - ) - ).toBe(true) - - expect( - imageTrace.files.some((file) => file.includes('public/another.jpg')) - ).toBe(true) - expect( - imageTrace.files.some((file) => file.includes('public/test.jpg')) - ).toBe(false) - expect( - imageTrace.files.some( - (file) => file === '../../../include-me-global.txt' - ) - ).toBe(true) - }) - } - ) + expect( + imageTrace.files.some((file) => file.includes('public/another.jpg')) + ).toBe(true) + expect( + imageTrace.files.some((file) => file.includes('public/test.jpg')) + ).toBe(false) + expect( + imageTrace.files.some( + (file) => file === '../../../include-me-global.txt' + ) + ).toBe(true) + }) + }) }) diff --git a/test/integration/build-warnings/test/index.test.js b/test/integration/build-warnings/test/index.test.js index 1586ad3fe5584..9b7a1cd262398 100644 --- a/test/integration/build-warnings/test/index.test.js +++ b/test/integration/build-warnings/test/index.test.js @@ -7,98 +7,95 @@ import { join } from 'path' const appDir = join(__dirname, '../') describe('Build warnings', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should not shown warning about minification without any modification', async () => { - const { stderr } = await nextBuild(appDir, undefined, { stderr: true }) - expect(stderr).not.toContain('optimization has been disabled') - }) - ;(process.env.IS_TURBOPACK_TEST ? it.skip : it)( - 'should shown warning about minification for minimize', - async () => { - const nextConfig = new File(join(appDir, 'next.config.js')) - - await waitFor(500) - - nextConfig.replace('true', 'false') - - const { stderr } = await nextBuild(appDir, undefined, { - stderr: true, - }) - - // eslint-disable-next-line jest/no-standalone-expect - expect(stderr).toContain('optimization has been disabled') - - nextConfig.restore() - } - ) - ;(process.env.IS_TURBOPACK_TEST ? it.skip : it)( - 'should shown warning about minification for minimizer', - async () => { - const nextConfig = new File(join(appDir, 'next.config.js')) - - await waitFor(500) - - nextConfig.replace( - 'config.optimization.minimize = true', - 'config.optimization.minimizer = []' - ) - - const { stderr } = await nextBuild(appDir, undefined, { - stderr: true, - }) - - // eslint-disable-next-line jest/no-standalone-expect - expect(stderr).toContain('optimization has been disabled') - - nextConfig.restore() - } - ) - - it('should not warn about missing cache in non-CI', async () => { - await remove(join(appDir, '.next')) - - const { stdout } = await nextBuild(appDir, undefined, { - stdout: true, - env: { - CI: '', - CIRCLECI: '', - TRAVIS: '', - SYSTEM_TEAMFOUNDATIONCOLLECTIONURI: '', - GITHUB_ACTIONS: '', - GITHUB_EVENT_NAME: '', - }, + describe('production mode', () => { + it('should not shown warning about minification without any modification', async () => { + const { stderr } = await nextBuild(appDir, undefined, { stderr: true }) + expect(stderr).not.toContain('optimization has been disabled') + }) + ;(process.env.IS_TURBOPACK_TEST ? it.skip : it)( + 'should shown warning about minification for minimize', + async () => { + const nextConfig = new File(join(appDir, 'next.config.js')) + + await waitFor(500) + + nextConfig.replace('true', 'false') + + const { stderr } = await nextBuild(appDir, undefined, { + stderr: true, }) - expect(stdout).not.toContain('no-cache') - }) - it('should not warn about missing cache on supported platforms', async () => { - await remove(join(appDir, '.next')) + // eslint-disable-next-line jest/no-standalone-expect + expect(stderr).toContain('optimization has been disabled') + + nextConfig.restore() + } + ) + ;(process.env.IS_TURBOPACK_TEST ? it.skip : it)( + 'should shown warning about minification for minimizer', + async () => { + const nextConfig = new File(join(appDir, 'next.config.js')) + + await waitFor(500) + + nextConfig.replace( + 'config.optimization.minimize = true', + 'config.optimization.minimizer = []' + ) - const { stdout } = await nextBuild(appDir, undefined, { - stdout: true, - env: { CI: '1', NOW_BUILDER: '1' }, + const { stderr } = await nextBuild(appDir, undefined, { + stderr: true, }) - expect(stdout).not.toContain('no-cache') + + // eslint-disable-next-line jest/no-standalone-expect + expect(stderr).toContain('optimization has been disabled') + + nextConfig.restore() + } + ) + + it('should not warn about missing cache in non-CI', async () => { + await remove(join(appDir, '.next')) + + const { stdout } = await nextBuild(appDir, undefined, { + stdout: true, + env: { + CI: '', + CIRCLECI: '', + TRAVIS: '', + SYSTEM_TEAMFOUNDATIONCOLLECTIONURI: '', + GITHUB_ACTIONS: '', + GITHUB_EVENT_NAME: '', + }, }) + expect(stdout).not.toContain('no-cache') + }) - it('should warn about missing cache in CI', async () => { - await remove(join(appDir, '.next')) + it('should not warn about missing cache on supported platforms', async () => { + await remove(join(appDir, '.next')) - let { stdout } = await nextBuild(appDir, undefined, { - stdout: true, - env: { CI: '1' }, - }) - expect(stdout).toContain('no-cache') - - // Do not warn after cache is present - ;({ stdout } = await nextBuild(appDir, undefined, { - stdout: true, - env: { CI: '1' }, - })) - expect(stdout).not.toContain('no-cache') + const { stdout } = await nextBuild(appDir, undefined, { + stdout: true, + env: { CI: '1', NOW_BUILDER: '1' }, + }) + expect(stdout).not.toContain('no-cache') + }) + + it('should warn about missing cache in CI', async () => { + await remove(join(appDir, '.next')) + + let { stdout } = await nextBuild(appDir, undefined, { + stdout: true, + env: { CI: '1' }, }) - } - ) + expect(stdout).toContain('no-cache') + + // Do not warn after cache is present + ;({ stdout } = await nextBuild(appDir, undefined, { + stdout: true, + env: { CI: '1' }, + })) + expect(stdout).not.toContain('no-cache') + }) + }) }) diff --git a/test/integration/catches-missing-getStaticProps/test/index.test.js b/test/integration/catches-missing-getStaticProps/test/index.test.js index ba34fdeaf9912..8d4fcd194e81f 100644 --- a/test/integration/catches-missing-getStaticProps/test/index.test.js +++ b/test/integration/catches-missing-getStaticProps/test/index.test.js @@ -13,28 +13,22 @@ const appDir = join(__dirname, '../') const errorRegex = /getStaticPaths was added without a getStaticProps in/ describe('Catches Missing getStaticProps', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it('should catch it in development mode', async () => { - const appPort = await findPort() - const app = await launchApp(appDir, appPort) - const html = await renderViaHTTP(appPort, '/hello') - await killApp(app) + describe('development mode', () => { + it('should catch it in development mode', async () => { + const appPort = await findPort() + const app = await launchApp(appDir, appPort) + const html = await renderViaHTTP(appPort, '/hello') + await killApp(app) - expect(html).toMatch(errorRegex) + expect(html).toMatch(errorRegex) + }) + }) + describe('production mode', () => { + it('should catch it in server build mode', async () => { + const { stderr } = await nextBuild(appDir, [], { + stderr: true, }) - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should catch it in server build mode', async () => { - const { stderr } = await nextBuild(appDir, [], { - stderr: true, - }) - expect(stderr).toMatch(errorRegex) - }) - } - ) + expect(stderr).toMatch(errorRegex) + }) + }) }) diff --git a/test/integration/chunking/test/index.test.js b/test/integration/chunking/test/index.test.js index 042976b4c732a..a5d6fabae393d 100644 --- a/test/integration/chunking/test/index.test.js +++ b/test/integration/chunking/test/index.test.js @@ -24,117 +24,112 @@ const existsChunkNamed = (name) => { // Skipped as it uses webpack internals / stats.json. ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)('Chunking', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - try { - // If a previous build has left chunks behind, delete them - const oldChunks = await readdir( - join(appDir, '.next', 'static', 'chunks') - ) - await Promise.all( - oldChunks.map((chunk) => { - return unlink(join(appDir, '.next', 'static', 'chunks', chunk)) - }) - ) - } catch (e) { - // Error here means old chunks don't exist, so we don't need to do anything - } - await nextBuild(appDir, []) - - stats = (await readFile(join(appDir, '.next', 'stats.json'), 'utf8')) - // fixes backslashes in keyNames not being escaped on windows - .replace(/"static\\(.*?":?)/g, (match) => - match.replace(/\\/g, '\\\\') - ) - - stats = JSON.parse(stats) - appPort = await findPort() - app = await nextStart(appDir, appPort) - chunks = await readdir(join(appDir, '.next', 'static', 'chunks')) - }) - - afterAll(() => killApp(app)) - - it('should use all url friendly names', () => { - expect(chunks).toEqual(chunks.map((name) => encodeURIComponent(name))) - }) - - it('should create a framework chunk', () => { - expect(existsChunkNamed('framework')).toBe(true) - }) - - it('should not create a commons chunk', () => { - // This app has no dependency that is required by ALL pages, and should - // therefore not have a commons chunk - expect(existsChunkNamed('commons')).toBe(false) - }) - - it('should not create a lib chunk for react or react-dom', () => { - // These large dependencies would become lib chunks, except that they - // are preemptively moved into the framework chunk. - expect(existsChunkNamed('react|react-dom')).toBe(false) - }) - - it('should not preload the build manifest', async () => { - const html = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(html) - expect( - [].slice - .call($('link[rel="preload"][as="script"]')) - .map((e) => e.attribs.href) - .some((entry) => entry.includes('_buildManifest')) - ).toBe(false) - }) - - it('should execute the build manifest', async () => { - const html = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(html) - expect( - Array.from($('script')) - .map((e) => e.attribs.src) - .some((entry) => entry && entry.includes('_buildManifest')) - ).toBe(true) - }) - - it('should not include more than one instance of react-dom', async () => { - const misplacedReactDom = stats.chunks.some((chunk) => { - if (chunk.names.includes('framework')) { - // disregard react-dom in framework--it's supposed to be there - return false - } - return chunk.modules.some((module) => { - return /react-dom/.test(module.name) + describe('production mode', () => { + beforeAll(async () => { + try { + // If a previous build has left chunks behind, delete them + const oldChunks = await readdir( + join(appDir, '.next', 'static', 'chunks') + ) + await Promise.all( + oldChunks.map((chunk) => { + return unlink(join(appDir, '.next', 'static', 'chunks', chunk)) }) + ) + } catch (e) { + // Error here means old chunks don't exist, so we don't need to do anything + } + await nextBuild(appDir, []) + + stats = (await readFile(join(appDir, '.next', 'stats.json'), 'utf8')) + // fixes backslashes in keyNames not being escaped on windows + .replace(/"static\\(.*?":?)/g, (match) => match.replace(/\\/g, '\\\\')) + + stats = JSON.parse(stats) + appPort = await findPort() + app = await nextStart(appDir, appPort) + chunks = await readdir(join(appDir, '.next', 'static', 'chunks')) + }) + + afterAll(() => killApp(app)) + + it('should use all url friendly names', () => { + expect(chunks).toEqual(chunks.map((name) => encodeURIComponent(name))) + }) + + it('should create a framework chunk', () => { + expect(existsChunkNamed('framework')).toBe(true) + }) + + it('should not create a commons chunk', () => { + // This app has no dependency that is required by ALL pages, and should + // therefore not have a commons chunk + expect(existsChunkNamed('commons')).toBe(false) + }) + + it('should not create a lib chunk for react or react-dom', () => { + // These large dependencies would become lib chunks, except that they + // are preemptively moved into the framework chunk. + expect(existsChunkNamed('react|react-dom')).toBe(false) + }) + + it('should not preload the build manifest', async () => { + const html = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(html) + expect( + [].slice + .call($('link[rel="preload"][as="script"]')) + .map((e) => e.attribs.href) + .some((entry) => entry.includes('_buildManifest')) + ).toBe(false) + }) + + it('should execute the build manifest', async () => { + const html = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(html) + expect( + Array.from($('script')) + .map((e) => e.attribs.src) + .some((entry) => entry && entry.includes('_buildManifest')) + ).toBe(true) + }) + + it('should not include more than one instance of react-dom', async () => { + const misplacedReactDom = stats.chunks.some((chunk) => { + if (chunk.names.includes('framework')) { + // disregard react-dom in framework--it's supposed to be there + return false + } + return chunk.modules.some((module) => { + return /react-dom/.test(module.name) }) - expect(misplacedReactDom).toBe(false) }) + expect(misplacedReactDom).toBe(false) + }) - describe('Serving', () => { - it('should hydrate with aggressive chunking', async () => { - const browser = await webdriver(appPort, '/page2') - const text = await browser.elementByCss('#padded-str').text() + describe('Serving', () => { + it('should hydrate with aggressive chunking', async () => { + const browser = await webdriver(appPort, '/page2') + const text = await browser.elementByCss('#padded-str').text() - expect(text).toBe('__rad__') + expect(text).toBe('__rad__') - await browser.close() - }) + await browser.close() + }) - it('should load chunks when navigating', async () => { - const browser = await webdriver(appPort, '/page3') - const text = await browser - .elementByCss('#page2-link') - .click() - .waitForElementByCss('#padded-str') - .elementByCss('#padded-str') - .text() + it('should load chunks when navigating', async () => { + const browser = await webdriver(appPort, '/page3') + const text = await browser + .elementByCss('#page2-link') + .click() + .waitForElementByCss('#padded-str') + .elementByCss('#padded-str') + .text() - expect(text).toBe('__rad__') + expect(text).toBe('__rad__') - await browser.close() - }) + await browser.close() }) - } - ) + }) + }) }) diff --git a/test/integration/clean-distdir/test/index.test.js b/test/integration/clean-distdir/test/index.test.js index 4ad38631e225a..485cde8bcc8c6 100644 --- a/test/integration/clean-distdir/test/index.test.js +++ b/test/integration/clean-distdir/test/index.test.js @@ -30,35 +30,32 @@ const runTests = () => { } describe('Cleaning distDir', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(() => { - fs.removeSync(nextDir) - }) - - runTests() - - describe('disabled write', () => { - beforeAll(async () => { - nextConfigContent = await fs.readFile(nextConfig, 'utf8') - await fs.writeFile( - nextConfig, - ` + describe('production mode', () => { + beforeAll(() => { + fs.removeSync(nextDir) + }) + + runTests() + + describe('disabled write', () => { + beforeAll(async () => { + nextConfigContent = await fs.readFile(nextConfig, 'utf8') + await fs.writeFile( + nextConfig, + ` module.exports = { cleanDistDir: false } ` - ) - }) - afterAll(async () => { - await fs.writeFile(nextConfig, nextConfigContent) - }) + ) + }) + afterAll(async () => { + await fs.writeFile(nextConfig, nextConfigContent) + }) - it('should not clean up .next before build start', async () => { - await checkFileWrite(true) - }) + it('should not clean up .next before build start', async () => { + await checkFileWrite(true) }) - } - ) + }) + }) }) diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index b373b9a76bb37..4834a52d519d9 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -84,286 +84,279 @@ const testExitSignal = async ( } describe('CLI Usage', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - describe('start', () => { - test('should exit when SIGINT is signalled', async () => { - require('console').log('before build') - await fs.remove(join(dirBasic, '.next')) - await nextBuild(dirBasic, undefined, { - onStdout(msg) { - console.log(msg) - }, - onStderr(msg) { - console.log(msg) - }, - }) - require('console').log('build finished') - - const port = await findPort() - await testExitSignal( - 'SIGINT', - ['start', dirBasic, '-p', port], - /- Local:/ - ) + describe('production mode', () => { + describe('start', () => { + test('should exit when SIGINT is signalled', async () => { + require('console').log('before build') + await fs.remove(join(dirBasic, '.next')) + await nextBuild(dirBasic, undefined, { + onStdout(msg) { + console.log(msg) + }, + onStderr(msg) { + console.log(msg) + }, }) - test('should exit when SIGTERM is signalled', async () => { - await fs.remove(join(dirBasic, '.next')) - await nextBuild(dirBasic, undefined, { - onStdout(msg) { - console.log(msg) - }, - onStderr(msg) { - console.log(msg) - }, - }) - const port = await findPort() - await testExitSignal( - 'SIGTERM', - ['start', dirBasic, '-p', port], - /- Local:/ - ) + require('console').log('build finished') + + const port = await findPort() + await testExitSignal( + 'SIGINT', + ['start', dirBasic, '-p', port], + /- Local:/ + ) + }) + test('should exit when SIGTERM is signalled', async () => { + await fs.remove(join(dirBasic, '.next')) + await nextBuild(dirBasic, undefined, { + onStdout(msg) { + console.log(msg) + }, + onStderr(msg) { + console.log(msg) + }, }) + const port = await findPort() + await testExitSignal( + 'SIGTERM', + ['start', dirBasic, '-p', port], + /- Local:/ + ) + }) - test('--help', async () => { - const help = await runNextCommand(['start', '--help'], { - stdout: true, - }) - expect(help.stdout).toMatch(/Starts Next.js in production mode/) + test('--help', async () => { + const help = await runNextCommand(['start', '--help'], { + stdout: true, }) + expect(help.stdout).toMatch(/Starts Next.js in production mode/) + }) - test('-h', async () => { - const help = await runNextCommand(['start', '-h'], { - stdout: true, - }) - expect(help.stdout).toMatch(/Starts Next.js in production mode/) + test('-h', async () => { + const help = await runNextCommand(['start', '-h'], { + stdout: true, }) + expect(help.stdout).toMatch(/Starts Next.js in production mode/) + }) + + test('should format IPv6 addresses correctly', async () => { + await nextBuild(dirBasic) + const port = await findPort() - test('should format IPv6 addresses correctly', async () => { - await nextBuild(dirBasic) - const port = await findPort() - - let stdout = '' - const app = await runNextCommandDev( - ['start', dirBasic, '--hostname', '::', '--port', port], - undefined, - { - nextStart: true, - onStdout(msg) { - stdout += msg - }, - } - ) - - try { - await check(() => { - // Only display when hostname is provided - expect(stdout).toMatch( - new RegExp(`Network:\\s*http://\\[::\\]:${port}`) - ) - expect(stdout).toMatch(new RegExp(`http://\\[::1\\]:${port}`)) - }) - } finally { - await killApp(app) + let stdout = '' + const app = await runNextCommandDev( + ['start', dirBasic, '--hostname', '::', '--port', port], + undefined, + { + nextStart: true, + onStdout(msg) { + stdout += msg + }, } - }) + ) - test('should warn when unknown argument provided', async () => { - const { stderr } = await runNextCommand(['start', '--random'], { - stderr: true, + try { + await check(() => { + // Only display when hostname is provided + expect(stdout).toMatch( + new RegExp(`Network:\\s*http://\\[::\\]:${port}`) + ) + expect(stdout).toMatch(new RegExp(`http://\\[::1\\]:${port}`)) }) - expect(stderr).toEqual(`error: unknown option '--random'\n`) + } finally { + await killApp(app) + } + }) + + test('should warn when unknown argument provided', async () => { + const { stderr } = await runNextCommand(['start', '--random'], { + stderr: true, }) - test('should not throw UnhandledPromiseRejectionWarning', async () => { - const { stderr } = await runNextCommand(['start', '--random'], { - stderr: true, - }) - expect(stderr).not.toContain('UnhandledPromiseRejectionWarning') + expect(stderr).toEqual(`error: unknown 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() + test('duplicate sass deps', async () => { + const port = await findPort() - let stderr = '' - let instance = await launchApp(dirDuplicateSass, port, { - stderr: true, - onStderr(msg) { - stderr += msg - }, - }) + 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).catch(() => {}) - } + try { + await check(() => stderr, /both `sass` and `node-sass` installed/) + } finally { + await killApp(instance).catch(() => {}) + } + }) + + 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('invalid directory', async () => { - const output = await runNextCommand(['start', 'non-existent'], { + test('--keepAliveTimeout string arg', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout', 'string'], + { stderr: true, - }) - expect(output.stderr).toContain( - 'Invalid project directory provided, no such directory' - ) - }) + } + ) + expect(stderr).toContain( + `error: option '--keepAliveTimeout ' argument 'string' is invalid. 'string' is not a non-negative number.` + ) + }) - test('--keepAliveTimeout string arg', async () => { - const { stderr } = await runNextCommand( - ['start', '--keepAliveTimeout', 'string'], - { - stderr: true, - } - ) - expect(stderr).toContain( - `error: option '--keepAliveTimeout ' argument 'string' is invalid. 'string' is not a non-negative number.` - ) - }) + test('--keepAliveTimeout negative number', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout=-100'], + { + stderr: true, + } + ) + expect(stderr).toContain( + `error: option '--keepAliveTimeout ' argument '-100' is invalid. '-100' is not a non-negative number.` + ) + }) - test('--keepAliveTimeout negative number', async () => { - const { stderr } = await runNextCommand( - ['start', '--keepAliveTimeout=-100'], - { - stderr: true, - } - ) - expect(stderr).toContain( - `error: option '--keepAliveTimeout ' argument '-100' is invalid. '-100' is not a non-negative number.` - ) - }) + test('--keepAliveTimeout Infinity', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout', 'Infinity'], + { + stderr: true, + } + ) + expect(stderr).toContain( + `error: option '--keepAliveTimeout ' argument 'Infinity' is invalid. 'Infinity' is not a non-negative number.` + ) + }) - test('--keepAliveTimeout Infinity', async () => { - const { stderr } = await runNextCommand( - ['start', '--keepAliveTimeout', 'Infinity'], - { - stderr: true, - } - ) - expect(stderr).toContain( - `error: option '--keepAliveTimeout ' argument 'Infinity' is invalid. 'Infinity' is not a non-negative number.` - ) - }) + test('--keepAliveTimeout happy path', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout', '100'], + { + stderr: true, + } + ) + expect(stderr).not.toContain( + `error: option '--keepAliveTimeout ' argument '100' is invalid. '100' is not a non-negative number.` + ) + }) - test('--keepAliveTimeout happy path', async () => { - const { stderr } = await runNextCommand( - ['start', '--keepAliveTimeout', '100'], - { - stderr: true, - } - ) - expect(stderr).not.toContain( - `error: option '--keepAliveTimeout ' argument '100' is invalid. '100' is not a non-negative number.` - ) - }) + test('should not start on a port out of range', async () => { + const invalidPort = '300001' + const { stderr } = await runNextCommand( + ['start', '--port', invalidPort], + { + stderr: true, + } + ) - test('should not start on a port out of range', async () => { - const invalidPort = '300001' - const { stderr } = await runNextCommand( - ['start', '--port', invalidPort], - { - stderr: true, - } - ) + expect(stderr).toContain(`options.port should be >= 0 and < 65536.`) + }) - expect(stderr).toContain(`options.port should be >= 0 and < 65536.`) - }) + test('should not start on a reserved port', async () => { + const reservedPort = '4045' + const { stderr } = await runNextCommand( + ['start', '--port', reservedPort], + { + stderr: true, + } + ) - test('should not start on a reserved port', async () => { - const reservedPort = '4045' - const { stderr } = await runNextCommand( - ['start', '--port', reservedPort], - { - stderr: true, - } - ) - - expect(stderr).toContain( - `Bad port: "${reservedPort}" is reserved for npp` - ) - }) + expect(stderr).toContain( + `Bad port: "${reservedPort}" is reserved for npp` + ) }) + }) - describe('telemetry', () => { - test('--help', async () => { - const help = await runNextCommand(['telemetry', '--help'], { - stdout: true, - }) - expect(help.stdout).toMatch( - /Allows you to enable or disable Next\.js'/ - ) + describe('telemetry', () => { + test('--help', async () => { + const help = await runNextCommand(['telemetry', '--help'], { + stdout: true, }) + expect(help.stdout).toMatch(/Allows you to enable or disable Next\.js'/) + }) - test('-h', async () => { - const help = await runNextCommand(['telemetry', '-h'], { - stdout: true, - }) - expect(help.stdout).toMatch( - /Allows you to enable or disable Next\.js'/ - ) + test('-h', async () => { + const help = await runNextCommand(['telemetry', '-h'], { + stdout: true, }) + expect(help.stdout).toMatch(/Allows you to enable or disable Next\.js'/) + }) - test('should warn when unknown argument provided', async () => { - const { stderr } = await runNextCommand(['telemetry', '--random'], { - stderr: true, - }) - expect(stderr).toEqual(`error: unknown option '--random'\n`) + test('should warn when unknown argument provided', async () => { + const { stderr } = await runNextCommand(['telemetry', '--random'], { + stderr: true, }) - test('should not throw UnhandledPromiseRejectionWarning', async () => { - const { stderr } = await runNextCommand(['telemetry', '--random'], { - stderr: true, - }) - expect(stderr).not.toContain('UnhandledPromiseRejectionWarning') + expect(stderr).toEqual(`error: unknown option '--random'\n`) + }) + test('should not throw UnhandledPromiseRejectionWarning', async () => { + const { stderr } = await runNextCommand(['telemetry', '--random'], { + stderr: true, }) + expect(stderr).not.toContain('UnhandledPromiseRejectionWarning') }) + }) - describe('build', () => { - test('--help', async () => { - const help = await runNextCommand(['build', '--help'], { - stdout: true, - }) - expect(help.stdout).toMatch(/Creates an optimized production build/) + describe('build', () => { + test('--help', async () => { + const help = await runNextCommand(['build', '--help'], { + stdout: true, }) + expect(help.stdout).toMatch(/Creates an optimized production build/) + }) - test('-h', async () => { - const help = await runNextCommand(['build', '-h'], { - stdout: true, - }) - expect(help.stdout).toMatch(/Creates an optimized production build/) + test('-h', async () => { + const help = await runNextCommand(['build', '-h'], { + stdout: true, }) + expect(help.stdout).toMatch(/Creates an optimized production build/) + }) - test('should warn when unknown argument provided', async () => { - const { stderr } = await runNextCommand(['build', '--random'], { - stderr: true, - }) - expect(stderr).toEqual(`error: unknown option '--random'\n`) + test('should warn when unknown argument provided', async () => { + const { stderr } = await runNextCommand(['build', '--random'], { + stderr: true, }) - test('should not throw UnhandledPromiseRejectionWarning', async () => { - const { stderr } = await runNextCommand(['build', '--random'], { - stderr: true, - }) - expect(stderr).not.toContain('UnhandledPromiseRejectionWarning') + expect(stderr).toEqual(`error: unknown option '--random'\n`) + }) + test('should not throw UnhandledPromiseRejectionWarning', async () => { + const { stderr } = await runNextCommand(['build', '--random'], { + stderr: true, }) + expect(stderr).not.toContain('UnhandledPromiseRejectionWarning') + }) - test('should exit when SIGINT is signalled', async () => { - await testExitSignal('SIGINT', ['build', dirBasic], undefined, 130) - }) + test('should exit when SIGINT is signalled', async () => { + await testExitSignal('SIGINT', ['build', dirBasic], undefined, 130) + }) - test('should exit when SIGTERM is signalled', async () => { - await testExitSignal('SIGTERM', ['build', dirBasic], undefined, 143) - }) + test('should exit when SIGTERM is signalled', async () => { + await testExitSignal('SIGTERM', ['build', dirBasic], undefined, 143) + }) - test('invalid directory', async () => { - const output = await runNextCommand(['build', 'non-existent'], { - stderr: true, - }) - expect(output.stderr).toContain( - 'Invalid project directory provided, no such directory' - ) + test('invalid directory', async () => { + const output = await runNextCommand(['build', 'non-existent'], { + stderr: true, }) + expect(output.stderr).toContain( + 'Invalid project directory provided, no such directory' + ) }) - } - ) + }) + }) describe('no command', () => { test('--help', async () => { diff --git a/test/integration/client-404/test/index.test.js b/test/integration/client-404/test/index.test.js index 8652af7a20236..7b3347ea8610e 100644 --- a/test/integration/client-404/test/index.test.js +++ b/test/integration/client-404/test/index.test.js @@ -75,32 +75,26 @@ const runTests = (isProd = false) => { } describe('Client 404', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - context.appPort = await findPort() - context.server = await launchApp(appDir, context.appPort) + describe('development mode', () => { + beforeAll(async () => { + context.appPort = await findPort() + context.server = await launchApp(appDir, context.appPort) - // pre-build page at the start - await renderViaHTTP(context.appPort, '/') - }) - afterAll(() => killApp(context.server)) + // pre-build page at the start + await renderViaHTTP(context.appPort, '/') + }) + afterAll(() => killApp(context.server)) - runTests() - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - context.appPort = await findPort() - context.server = await nextStart(appDir, context.appPort) - }) - afterAll(() => killApp(context.server)) + runTests() + }) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + context.appPort = await findPort() + context.server = await nextStart(appDir, context.appPort) + }) + afterAll(() => killApp(context.server)) - runTests(true) - } - ) + runTests(true) + }) }) diff --git a/test/integration/client-shallow-routing/test/index.test.js b/test/integration/client-shallow-routing/test/index.test.js index 5c1b4d0dfb451..0a61028ea0979 100644 --- a/test/integration/client-shallow-routing/test/index.test.js +++ b/test/integration/client-shallow-routing/test/index.test.js @@ -88,29 +88,23 @@ const runTests = () => { } describe('Client Shallow Routing', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(() => killApp(app)) - - runTests() - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - - runTests() - } - ) + describe('development mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) }) diff --git a/test/integration/config-experimental-warning/test/index.test.js b/test/integration/config-experimental-warning/test/index.test.js index fb7e3f2ee7e68..92d04c3eef057 100644 --- a/test/integration/config-experimental-warning/test/index.test.js +++ b/test/integration/config-experimental-warning/test/index.test.js @@ -172,11 +172,9 @@ describe('Config Experimental Warning', () => { expect(stdout).toContain(' ✓ workerThreads') expect(stdout).toContain(' ✓ scrollRestoration') }) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should not show next app info in next start', async () => { - configFile.write(` + describe('production mode', () => { + it('should not show next app info in next start', async () => { + configFile.write(` module.exports = { experimental: { workerThreads: true, @@ -187,19 +185,19 @@ describe('Config Experimental Warning', () => { } `) - await collectStdoutFromBuild(appDir) - const port = await findPort() - let stdout = '' - app = await nextStart(appDir, port, { - onStdout(msg) { - stdout += msg - }, - }) - expect(stdout).not.toMatch(experimentalHeader) + await collectStdoutFromBuild(appDir) + const port = await findPort() + let stdout = '' + app = await nextStart(appDir, port, { + onStdout(msg) { + stdout += msg + }, }) + expect(stdout).not.toMatch(experimentalHeader) + }) - it('should show next app info with all experimental features in next build', async () => { - configFile.write(` + it('should show next app info with all experimental features in next build', async () => { + configFile.write(` module.exports = { experimental: { workerThreads: true, @@ -210,17 +208,17 @@ describe('Config Experimental Warning', () => { } } `) - const stdout = await collectStdoutFromBuild(appDir) - expect(stdout).toMatch(experimentalHeader) - expect(stdout).toMatch(' · cpus: 2') - expect(stdout).toMatch(' ✓ workerThreads') - expect(stdout).toMatch(' ✓ scrollRestoration') - expect(stdout).toMatch(' ⨯ prerenderEarlyExit') - expect(stdout).toMatch(' ✓ parallelServerCompiles') - }) - - it('should show unrecognized experimental features in warning but not in start log experiments section', async () => { - configFile.write(` + const stdout = await collectStdoutFromBuild(appDir) + expect(stdout).toMatch(experimentalHeader) + expect(stdout).toMatch(' · cpus: 2') + expect(stdout).toMatch(' ✓ workerThreads') + expect(stdout).toMatch(' ✓ scrollRestoration') + expect(stdout).toMatch(' ⨯ prerenderEarlyExit') + expect(stdout).toMatch(' ✓ parallelServerCompiles') + }) + + it('should show unrecognized experimental features in warning but not in start log experiments section', async () => { + configFile.write(` module.exports = { experimental: { appDir: true @@ -228,28 +226,27 @@ describe('Config Experimental Warning', () => { } `) - await collectStdoutFromBuild(appDir) - const port = await findPort() - let stdout = '' - let stderr = '' - app = await nextStart(appDir, port, { - onStdout(msg) { - stdout += msg - }, - onStderr(msg) { - stderr += msg - }, - }) - - await check(() => { - const cliOutput = stripAnsi(stdout) - const cliOutputErr = stripAnsi(stderr) - expect(cliOutput).not.toContain(experimentalHeader) - expect(cliOutputErr).toContain( - `Unrecognized key(s) in object: 'appDir' at "experimental"` - ) - }) + await collectStdoutFromBuild(appDir) + const port = await findPort() + let stdout = '' + let stderr = '' + app = await nextStart(appDir, port, { + onStdout(msg) { + stdout += msg + }, + onStderr(msg) { + stderr += msg + }, }) - } - ) + + await check(() => { + const cliOutput = stripAnsi(stdout) + const cliOutputErr = stripAnsi(stderr) + expect(cliOutput).not.toContain(experimentalHeader) + expect(cliOutputErr).toContain( + `Unrecognized key(s) in object: 'appDir' at "experimental"` + ) + }) + }) + }) }) diff --git a/test/integration/config-promise-error/test/index.test.js b/test/integration/config-promise-error/test/index.test.js index 717a7af367165..7e50236c48370 100644 --- a/test/integration/config-promise-error/test/index.test.js +++ b/test/integration/config-promise-error/test/index.test.js @@ -9,15 +9,13 @@ const appDir = join(__dirname, '..') ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( 'Promise in next config', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - afterEach(() => fs.remove(join(appDir, 'next.config.js'))) + describe('production mode', () => { + afterEach(() => fs.remove(join(appDir, 'next.config.js'))) - it('should warn when a promise is returned on webpack', async () => { - fs.writeFile( - join(appDir, 'next.config.js'), - ` + it('should warn when a promise is returned on webpack', async () => { + fs.writeFile( + join(appDir, 'next.config.js'), + ` module.exports = (phase, { isServer }) => { return { webpack: async (config) => { @@ -26,17 +24,16 @@ const appDir = join(__dirname, '..') } } ` - ) + ) - const { stderr, stdout } = await nextBuild(appDir, undefined, { - stderr: true, - stdout: true, - }) - expect(stderr + stdout).toMatch( - /> Promise returned in next config\. https:\/\// - ) + const { stderr, stdout } = await nextBuild(appDir, undefined, { + stderr: true, + stdout: true, }) - } - ) + expect(stderr + stdout).toMatch( + /> Promise returned in next config\. https:\/\// + ) + }) + }) } ) diff --git a/test/integration/config-syntax-error/test/index.test.js b/test/integration/config-syntax-error/test/index.test.js index 6a02b3bd43ea4..ae7bfe024a6d6 100644 --- a/test/integration/config-syntax-error/test/index.test.js +++ b/test/integration/config-syntax-error/test/index.test.js @@ -8,49 +8,46 @@ const nextConfigJS = join(appDir, 'next.config.js') const nextConfigMJS = join(appDir, 'next.config.mjs') describe('Invalid config syntax', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('should error when next.config.js contains syntax error', async () => { - await fs.writeFile( - nextConfigJS, - ` + describe('production mode', () => { + it('should error when next.config.js contains syntax error', async () => { + await fs.writeFile( + nextConfigJS, + ` module.exports = { reactStrictMode: true,, } ` - ) - const { stderr } = await nextBuild(appDir, undefined, { - stderr: true, - }) - await fs.remove(nextConfigJS) - - expect(stderr).toContain( - 'Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error' - ) - expect(stderr).toContain('SyntaxError') + ) + const { stderr } = await nextBuild(appDir, undefined, { + stderr: true, }) + await fs.remove(nextConfigJS) + + expect(stderr).toContain( + 'Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error' + ) + expect(stderr).toContain('SyntaxError') + }) - it('should error when next.config.mjs contains syntax error', async () => { - await fs.writeFile( - nextConfigMJS, - ` + it('should error when next.config.mjs contains syntax error', async () => { + await fs.writeFile( + nextConfigMJS, + ` const config = { reactStrictMode: true,, } export default config ` - ) - const { stderr } = await nextBuild(appDir, undefined, { - stderr: true, - }) - await fs.remove(nextConfigMJS) - - expect(stderr).toContain( - 'Failed to load next.config.mjs, see more info here https://nextjs.org/docs/messages/next-config-error' - ) - expect(stderr).toContain('SyntaxError') + ) + const { stderr } = await nextBuild(appDir, undefined, { + stderr: true, }) - } - ) + await fs.remove(nextConfigMJS) + + expect(stderr).toContain( + 'Failed to load next.config.mjs, see more info here https://nextjs.org/docs/messages/next-config-error' + ) + expect(stderr).toContain('SyntaxError') + }) + }) }) diff --git a/test/integration/config-validation/test/index.test.ts b/test/integration/config-validation/test/index.test.ts index ef31410d06056..9881245abdf33 100644 --- a/test/integration/config-validation/test/index.test.ts +++ b/test/integration/config-validation/test/index.test.ts @@ -5,13 +5,11 @@ import fs from 'fs-extra' const nextConfigPath = path.join(__dirname, '../next.config.js') describe('next.config.js validation', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it.each([ - { - name: 'invalid config types', - configContent: ` + describe('production mode', () => { + it.each([ + { + name: 'invalid config types', + configContent: ` module.exports = { rewrites: true, images: { @@ -19,14 +17,14 @@ describe('next.config.js validation', () => { } } `, - outputs: [ - `received 'something' at "images.loader"`, - 'Expected function, received boolean at "rewrites"', - ], - }, - { - name: 'unexpected config fields', - configContent: ` + outputs: [ + `received 'something' at "images.loader"`, + 'Expected function, received boolean at "rewrites"', + ], + }, + { + name: 'unexpected config fields', + configContent: ` module.exports = { nonExistent: true, experimental: { @@ -34,44 +32,40 @@ describe('next.config.js validation', () => { } } `, - outputs: [ - `Unrecognized key(s) in object: 'nonExistent'`, - `Unrecognized key(s) in object: 'anotherNonExistent' at "experimental"`, - ], - }, - { - name: 'invalid config array lengths', - configContent: ` + outputs: [ + `Unrecognized key(s) in object: 'nonExistent'`, + `Unrecognized key(s) in object: 'anotherNonExistent' at "experimental"`, + ], + }, + { + name: 'invalid config array lengths', + configContent: ` module.exports = { pageExtensions: [] } `, - outputs: [ - 'Array must contain at least 1 element(s) at "pageExtensions"', - ], - }, - ])( - 'it should validate correctly for $name', - async ({ outputs, configContent }) => { - await fs.writeFile(nextConfigPath, configContent) - const result = await nextBuild( - path.join(__dirname, '../'), - undefined, - { - stderr: true, - stdout: true, - } - ) - await fs.remove(nextConfigPath) + outputs: [ + 'Array must contain at least 1 element(s) at "pageExtensions"', + ], + }, + ])( + 'it should validate correctly for $name', + async ({ outputs, configContent }) => { + await fs.writeFile(nextConfigPath, configContent) + const result = await nextBuild(path.join(__dirname, '../'), undefined, { + stderr: true, + stdout: true, + }) + await fs.remove(nextConfigPath) - for (const output of outputs) { - expect(result.stdout + result.stderr).toContain(output) - } + for (const output of outputs) { + expect(result.stdout + result.stderr).toContain(output) } - ) + } + ) - it('should allow undefined environment variables', async () => { - const configContent = ` + it('should allow undefined environment variables', async () => { + const configContent = ` module.exports = { env: { FOO: 'bar', @@ -80,18 +74,17 @@ describe('next.config.js validation', () => { } ` - await fs.writeFile(nextConfigPath, configContent) - const result = await nextBuild(path.join(__dirname, '../'), undefined, { - stderr: true, - stdout: true, - }) + await fs.writeFile(nextConfigPath, configContent) + const result = await nextBuild(path.join(__dirname, '../'), undefined, { + stderr: true, + stdout: true, + }) - await fs.remove(nextConfigPath) + await fs.remove(nextConfigPath) - expect(result.stdout + result.stderr).not.toContain( - '"env.QUX" is missing' - ) - }) - } - ) + expect(result.stdout + result.stderr).not.toContain( + '"env.QUX" is missing' + ) + }) + }) }) diff --git a/test/integration/conflicting-public-file-page/test/index.test.js b/test/integration/conflicting-public-file-page/test/index.test.js index 8713e55f1ff23..bddafdd57b783 100644 --- a/test/integration/conflicting-public-file-page/test/index.test.js +++ b/test/integration/conflicting-public-file-page/test/index.test.js @@ -12,52 +12,45 @@ import { const appDir = path.join(__dirname, '..') describe('Errors on conflict between public file and page file', () => { - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - it('Throws error during development', async () => { - const appPort = await findPort() - let output = '' - const app = await launchApp(appDir, appPort, { - onStdout: (data) => { - output += data.toString() - }, - onStderr: (data) => { - output += data.toString() - }, - }) - - const regex = - /A conflicting public file and page file was found for path/ - - const conflicts = ['/another/conflict', '/hello'] - for (const conflict of conflicts) { - const html = await renderViaHTTP(appPort, conflict) - expect(html).toMatch(regex) - } - - expect(output).toMatch(regex) - - await killApp(app) + describe('development mode', () => { + it('Throws error during development', async () => { + const appPort = await findPort() + let output = '' + const app = await launchApp(appDir, appPort, { + onStdout: (data) => { + output += data.toString() + }, + onStderr: (data) => { + output += data.toString() + }, }) - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - it('Throws error during build', async () => { - const conflicts = ['/another/conflict', '/another', '/hello'] - const results = await nextBuild(appDir, [], { - stdout: true, - stderr: true, - }) - const output = results.stdout + results.stderr - expect(output).toMatch(/Conflicting public and page files were found/) - - for (const conflict of conflicts) { - expect(output.indexOf(conflict) > 0).toBe(true) - } + + const regex = /A conflicting public file and page file was found for path/ + + const conflicts = ['/another/conflict', '/hello'] + for (const conflict of conflicts) { + const html = await renderViaHTTP(appPort, conflict) + expect(html).toMatch(regex) + } + + expect(output).toMatch(regex) + + await killApp(app) + }) + }) + describe('production mode', () => { + it('Throws error during build', async () => { + const conflicts = ['/another/conflict', '/another', '/hello'] + const results = await nextBuild(appDir, [], { + stdout: true, + stderr: true, }) - } - ) + const output = results.stdout + results.stderr + expect(output).toMatch(/Conflicting public and page files were found/) + + for (const conflict of conflicts) { + expect(output.indexOf(conflict) > 0).toBe(true) + } + }) + }) }) diff --git a/test/integration/conflicting-ssg-paths/test/index.test.js b/test/integration/conflicting-ssg-paths/test/index.test.js index a3e43a83ccbb2..f23cc21d84396 100644 --- a/test/integration/conflicting-ssg-paths/test/index.test.js +++ b/test/integration/conflicting-ssg-paths/test/index.test.js @@ -8,16 +8,14 @@ const appDir = join(__dirname, '../') const pagesDir = join(appDir, 'pages') describe('Conflicting SSG paths', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - afterEach(() => fs.remove(pagesDir)) - - it('should show proper error when two dynamic SSG routes have conflicting paths', async () => { - await fs.ensureDir(join(pagesDir, 'blog')) - await fs.writeFile( - join(pagesDir, 'blog/[slug].js'), - ` + describe('production mode', () => { + afterEach(() => fs.remove(pagesDir)) + + it('should show proper error when two dynamic SSG routes have conflicting paths', async () => { + await fs.ensureDir(join(pagesDir, 'blog')) + await fs.writeFile( + join(pagesDir, 'blog/[slug].js'), + ` export const getStaticProps = () => { return { props: {} @@ -38,11 +36,11 @@ describe('Conflicting SSG paths', () => { return '/blog/[slug]' } ` - ) + ) - await fs.writeFile( - join(pagesDir, '[...catchAll].js'), - ` + await fs.writeFile( + join(pagesDir, '[...catchAll].js'), + ` export const getStaticProps = () => { return { props: {} @@ -63,39 +61,39 @@ describe('Conflicting SSG paths', () => { return '/[catchAll]' } ` - ) - - const result = await nextBuild(appDir, undefined, { - stdout: true, - stderr: true, - }) - const output = result.stdout + result.stderr - expect(output).toContain( - 'Conflicting paths returned from getStaticPaths, paths must be unique per page' - ) - expect(output).toContain( - 'https://nextjs.org/docs/messages/conflicting-ssg-paths' - ) - expect(output).toContain( - `path: "/blog/conflicting" from page: "/[...catchAll]"` - ) - expect(output).toContain(`conflicts with path: "/blog/conflicting"`) - }) + ) - it('should show proper error when a dynamic SSG route conflicts with normal route', async () => { - await fs.ensureDir(join(pagesDir, 'hello')) - await fs.writeFile( - join(pagesDir, 'hello/world.js'), - ` + const result = await nextBuild(appDir, undefined, { + stdout: true, + stderr: true, + }) + const output = result.stdout + result.stderr + expect(output).toContain( + 'Conflicting paths returned from getStaticPaths, paths must be unique per page' + ) + expect(output).toContain( + 'https://nextjs.org/docs/messages/conflicting-ssg-paths' + ) + expect(output).toContain( + `path: "/blog/conflicting" from page: "/[...catchAll]"` + ) + expect(output).toContain(`conflicts with path: "/blog/conflicting"`) + }) + + it('should show proper error when a dynamic SSG route conflicts with normal route', async () => { + await fs.ensureDir(join(pagesDir, 'hello')) + await fs.writeFile( + join(pagesDir, 'hello/world.js'), + ` export default function Page() { return '/hello/world' } ` - ) + ) - await fs.writeFile( - join(pagesDir, '[...catchAll].js'), - ` + await fs.writeFile( + join(pagesDir, '[...catchAll].js'), + ` export const getStaticProps = () => { return { props: {} @@ -116,40 +114,40 @@ describe('Conflicting SSG paths', () => { return '/[catchAll]' } ` - ) - - const result = await nextBuild(appDir, undefined, { - stdout: true, - stderr: true, - }) - const output = result.stdout + result.stderr - expect(output).toContain( - 'Conflicting paths returned from getStaticPaths, paths must be unique per page' - ) - expect(output).toContain( - 'https://nextjs.org/docs/messages/conflicting-ssg-paths' - ) - expect(output).toContain( - `path: "/hellO/world" from page: "/[...catchAll]" conflicts with path: "/hello/world"` - ) - }) + ) - it('should show proper error when a dynamic SSG route conflicts with SSR route', async () => { - await fs.ensureDir(join(pagesDir, 'hello')) - await fs.writeFile( - join(pagesDir, 'hello/world.js'), - ` + const result = await nextBuild(appDir, undefined, { + stdout: true, + stderr: true, + }) + const output = result.stdout + result.stderr + expect(output).toContain( + 'Conflicting paths returned from getStaticPaths, paths must be unique per page' + ) + expect(output).toContain( + 'https://nextjs.org/docs/messages/conflicting-ssg-paths' + ) + expect(output).toContain( + `path: "/hellO/world" from page: "/[...catchAll]" conflicts with path: "/hello/world"` + ) + }) + + it('should show proper error when a dynamic SSG route conflicts with SSR route', async () => { + await fs.ensureDir(join(pagesDir, 'hello')) + await fs.writeFile( + join(pagesDir, 'hello/world.js'), + ` export const getServerSideProps = () => ({ props: {} }) export default function Page() { return '/hello/world' } ` - ) + ) - await fs.writeFile( - join(pagesDir, '[...catchAll].js'), - ` + await fs.writeFile( + join(pagesDir, '[...catchAll].js'), + ` export const getStaticProps = () => { return { props: {} @@ -170,23 +168,22 @@ describe('Conflicting SSG paths', () => { return '/[catchAll]' } ` - ) - - const result = await nextBuild(appDir, undefined, { - stdout: true, - stderr: true, - }) - const output = result.stdout + result.stderr - expect(output).toContain( - 'Conflicting paths returned from getStaticPaths, paths must be unique per page' - ) - expect(output).toContain( - 'https://nextjs.org/docs/messages/conflicting-ssg-paths' - ) - expect(output).toContain( - `path: "/hellO/world" from page: "/[...catchAll]" conflicts with path: "/hello/world"` - ) + ) + + const result = await nextBuild(appDir, undefined, { + stdout: true, + stderr: true, }) - } - ) + const output = result.stdout + result.stderr + expect(output).toContain( + 'Conflicting paths returned from getStaticPaths, paths must be unique per page' + ) + expect(output).toContain( + 'https://nextjs.org/docs/messages/conflicting-ssg-paths' + ) + expect(output).toContain( + `path: "/hellO/world" from page: "/[...catchAll]" conflicts with path: "/hello/world"` + ) + }) + }) }) diff --git a/test/integration/critical-css/test/index.test.js b/test/integration/critical-css/test/index.test.js index acd225bb90a53..5396bf568fb4d 100644 --- a/test/integration/critical-css/test/index.test.js +++ b/test/integration/critical-css/test/index.test.js @@ -57,28 +57,25 @@ function runTests() { } describe('CSS optimization for SSR apps', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await fs.writeFile( - nextConfig, - `module.exports = { experimental: {optimizeCss: true} }`, - 'utf8' - ) + describe('production mode', () => { + beforeAll(async () => { + await fs.writeFile( + nextConfig, + `module.exports = { experimental: {optimizeCss: true} }`, + 'utf8' + ) - if (fs.pathExistsSync(join(appDir, '.next'))) { - await fs.remove(join(appDir, '.next')) - } - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - await fs.remove(nextConfig) - }) - runTests() - } - ) + if (fs.pathExistsSync(join(appDir, '.next'))) { + await fs.remove(join(appDir, '.next')) + } + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + await fs.remove(nextConfig) + }) + runTests() + }) }) diff --git a/test/integration/css-client-nav/test/index.test.js b/test/integration/css-client-nav/test/index.test.js index 8903cbc17aed0..d159e7c461ffe 100644 --- a/test/integration/css-client-nav/test/index.test.js +++ b/test/integration/css-client-nav/test/index.test.js @@ -150,78 +150,75 @@ function runTests(dev) { } describe('CSS Module client-side navigation', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await remove(join(appDir, '.next')) - await nextBuild(appDir) - const port = await findPort() - app = await nextStart(appDir, port) - appPort = await findPort() - - const proxy = httpProxy.createProxyServer({ - target: `http://localhost:${port}`, - }) - - proxyServer = http.createServer(async (req, res) => { - if (stallCss && req.url.endsWith('.css')) { - console.log('stalling request for', req.url) - await new Promise((resolve) => setTimeout(resolve, 5 * 1000)) - } - proxy.web(req, res) - }) - - proxy.on('error', (err) => { - console.warn('Failed to proxy', err) - }) - - await new Promise((resolve) => { - proxyServer.listen(appPort, () => resolve()) - }) - }) - afterAll(async () => { - proxyServer.close() - await killApp(app) + describe('production mode', () => { + beforeAll(async () => { + await remove(join(appDir, '.next')) + await nextBuild(appDir) + const port = await findPort() + app = await nextStart(appDir, port) + appPort = await findPort() + + const proxy = httpProxy.createProxyServer({ + target: `http://localhost:${port}`, }) - it('should time out and hard navigate for stalled CSS request', async () => { - let browser - stallCss = true - - try { - browser = await webdriver(appPort, '/red') - await browser.eval('window.beforeNav = "hello"') - - const redColor = await browser.eval( - `window.getComputedStyle(document.querySelector('#verify-red')).color` - ) - expect(redColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`) - expect(await browser.eval('window.beforeNav')).toBe('hello') - - await browser.elementByCss('#link-blue').click() - - await browser.waitForElementByCss('#verify-blue') - - const blueColor = await browser.eval( - `window.getComputedStyle(document.querySelector('#verify-blue')).color` - ) - expect(blueColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`) - - // the timeout should have been reached and we did a hard - // navigation - expect(await browser.eval('window.beforeNav')).toBeFalsy() - } finally { - stallCss = false - if (browser) { - await browser.close() - } + proxyServer = http.createServer(async (req, res) => { + if (stallCss && req.url.endsWith('.css')) { + console.log('stalling request for', req.url) + await new Promise((resolve) => setTimeout(resolve, 5 * 1000)) } + proxy.web(req, res) }) - runTests() - } - ) + proxy.on('error', (err) => { + console.warn('Failed to proxy', err) + }) + + await new Promise((resolve) => { + proxyServer.listen(appPort, () => resolve()) + }) + }) + afterAll(async () => { + proxyServer.close() + await killApp(app) + }) + + it('should time out and hard navigate for stalled CSS request', async () => { + let browser + stallCss = true + + try { + browser = await webdriver(appPort, '/red') + await browser.eval('window.beforeNav = "hello"') + + const redColor = await browser.eval( + `window.getComputedStyle(document.querySelector('#verify-red')).color` + ) + expect(redColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`) + expect(await browser.eval('window.beforeNav')).toBe('hello') + + await browser.elementByCss('#link-blue').click() + + await browser.waitForElementByCss('#verify-blue') + + const blueColor = await browser.eval( + `window.getComputedStyle(document.querySelector('#verify-blue')).color` + ) + expect(blueColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`) + + // the timeout should have been reached and we did a hard + // navigation + expect(await browser.eval('window.beforeNav')).toBeFalsy() + } finally { + stallCss = false + if (browser) { + await browser.close() + } + } + }) + + runTests() + }) describe('dev', () => { beforeAll(async () => { diff --git a/test/integration/css-customization/test/index.test.js b/test/integration/css-customization/test/index.test.js index c6121c5cca56b..ba00c2e03a12d 100644 --- a/test/integration/css-customization/test/index.test.js +++ b/test/integration/css-customization/test/index.test.js @@ -12,62 +12,59 @@ const BUILD_FAILURE_RE = /Build failed because of (webpack|Rspack) errors/ ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( 'CSS Customization', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'custom-configuration') + describe('production mode', () => { + const appDir = join(fixturesDir, 'custom-configuration') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - describe('Basic CSS', () => { - it('should compile successfully', async () => { - const { code, stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) + describe('Basic CSS', () => { + it('should compile successfully', async () => { + const { code, stdout } = await nextBuild(appDir, [], { + stdout: true, }) + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) - it(`should've compiled and prefixed`, async () => { - const cssFolder = join(appDir, '.next/static/css') - - const files = await readdir(cssFolder) - const cssFiles = files.filter((f) => /\.css$/.test(f)) - - expect(cssFiles.length).toBe(1) - const cssContent = await readFile( - join(cssFolder, cssFiles[0]), - 'utf8' - ) - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `"@media (480px <= width < 768px){::placeholder{color:green}}.video{max-width:400px;max-height:300px}"` - ) - - // Contains a source map - expect(cssContent).toMatch( - /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// - ) - }) + it(`should've compiled and prefixed`, async () => { + const cssFolder = join(appDir, '.next/static/css') + + const files = await readdir(cssFolder) + const cssFiles = files.filter((f) => /\.css$/.test(f)) + + expect(cssFiles.length).toBe(1) + const cssContent = await readFile( + join(cssFolder, cssFiles[0]), + 'utf8' + ) + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `"@media (480px <= width < 768px){::placeholder{color:green}}.video{max-width:400px;max-height:300px}"` + ) + + // Contains a source map + expect(cssContent).toMatch( + /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// + ) + }) - it(`should've emitted a source map`, async () => { - const cssFolder = join(appDir, '.next/static/css') + it(`should've emitted a source map`, async () => { + const cssFolder = join(appDir, '.next/static/css') - const files = await readdir(cssFolder) - const cssMapFiles = files.filter((f) => /\.css\.map$/.test(f)) + const files = await readdir(cssFolder) + const cssMapFiles = files.filter((f) => /\.css\.map$/.test(f)) - expect(cssMapFiles.length).toBe(1) - const cssMapContent = ( - await readFile(join(cssFolder, cssMapFiles[0]), 'utf8') - ).trim() + expect(cssMapFiles.length).toBe(1) + const cssMapContent = ( + await readFile(join(cssFolder, cssMapFiles[0]), 'utf8') + ).trim() - const { version, mappings, sourcesContent } = - JSON.parse(cssMapContent) - expect({ version, mappings, sourcesContent }) - .toMatchInlineSnapshot(` + const { version, mappings, sourcesContent } = + JSON.parse(cssMapContent) + expect({ version, mappings, sourcesContent }).toMatchInlineSnapshot(` { "mappings": "AACA,gCACE,cACE,WACF,CACF,CAGA,OACE,eAA0B,CAA1B,gBACF", "sourcesContent": [ @@ -87,62 +84,61 @@ const BUILD_FAILURE_RE = /Build failed because of (webpack|Rspack) errors/ "version": 3, } `) - }) }) + }) - describe('Correct CSS Customization Array', () => { - const appDir = join(fixturesDir, 'custom-configuration-arr') + describe('Correct CSS Customization Array', () => { + const appDir = join(fixturesDir, 'custom-configuration-arr') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should compile successfully', async () => { - const { code, stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) + it('should compile successfully', async () => { + const { code, stdout } = await nextBuild(appDir, [], { + stdout: true, }) + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) - it(`should've compiled and prefixed`, async () => { - const cssFolder = join(appDir, '.next/static/css') - - const files = await readdir(cssFolder) - const cssFiles = files.filter((f) => /\.css$/.test(f)) - - expect(cssFiles.length).toBe(1) - const cssContent = await readFile( - join(cssFolder, cssFiles[0]), - 'utf8' - ) - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `"@media (480px <= width < 768px){a:before{content:""}::placeholder{color:green}}.video{max-width:6400px;max-height:4800px;max-width:400rem;max-height:300rem}"` - ) - - // Contains a source map - expect(cssContent).toMatch( - /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// - ) - }) + it(`should've compiled and prefixed`, async () => { + const cssFolder = join(appDir, '.next/static/css') + + const files = await readdir(cssFolder) + const cssFiles = files.filter((f) => /\.css$/.test(f)) + + expect(cssFiles.length).toBe(1) + const cssContent = await readFile( + join(cssFolder, cssFiles[0]), + 'utf8' + ) + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `"@media (480px <= width < 768px){a:before{content:""}::placeholder{color:green}}.video{max-width:6400px;max-height:4800px;max-width:400rem;max-height:300rem}"` + ) + + // Contains a source map + expect(cssContent).toMatch( + /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// + ) + }) - it(`should've emitted a source map`, async () => { - const cssFolder = join(appDir, '.next/static/css') + it(`should've emitted a source map`, async () => { + const cssFolder = join(appDir, '.next/static/css') - const files = await readdir(cssFolder) - const cssMapFiles = files.filter((f) => /\.css\.map$/.test(f)) + const files = await readdir(cssFolder) + const cssMapFiles = files.filter((f) => /\.css\.map$/.test(f)) - expect(cssMapFiles.length).toBe(1) - const cssMapContent = ( - await readFile(join(cssFolder, cssMapFiles[0]), 'utf8') - ).trim() + expect(cssMapFiles.length).toBe(1) + const cssMapContent = ( + await readFile(join(cssFolder, cssMapFiles[0]), 'utf8') + ).trim() - const { version, mappings, sourcesContent } = - JSON.parse(cssMapContent) - expect({ version, mappings, sourcesContent }) - .toMatchInlineSnapshot(` + const { version, mappings, sourcesContent } = + JSON.parse(cssMapContent) + expect({ version, mappings, sourcesContent }).toMatchInlineSnapshot(` { "mappings": "AACA,gCACE,SACE,UACF,CACA,cACE,WACF,CACF,CAGA,OACE,gBAA4B,CAA5B,iBAA4B,CAA5B,gBAA4B,CAA5B,iBACF", "sourcesContent": [ @@ -165,257 +161,252 @@ const BUILD_FAILURE_RE = /Build failed because of (webpack|Rspack) errors/ "version": 3, } `) - }) }) + }) - describe('Correct CSS Customization custom loader', () => { - const appDir = join(fixturesDir, 'custom-configuration-loader') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - - it('should compile successfully', async () => { - const { code, stdout, stderr } = await nextBuild(appDir, [], { - stdout: true, - stderr: true, - }) - expect(code).toBe(0) - expect(stderr).toMatch(/Built-in CSS support is being disabled/) - expect(stdout).toMatch(/Compiled successfully/) - }) - - it(`should've applied style`, async () => { - const pagesFolder = join(appDir, '.next/static/chunks/pages') + describe('Correct CSS Customization custom loader', () => { + const appDir = join(fixturesDir, 'custom-configuration-loader') - const files = await readdir(pagesFolder) - const indexFiles = files.filter((f) => /^index.+\.js$/.test(f)) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - expect(indexFiles.length).toBe(1) - const indexContent = await readFile( - join(pagesFolder, indexFiles[0]), - 'utf8' - ) - expect(indexContent).toMatch(/\.my-text\.jsx-[0-9a-z]+{color:red}/) + it('should compile successfully', async () => { + const { code, stdout, stderr } = await nextBuild(appDir, [], { + stdout: true, + stderr: true, }) + expect(code).toBe(0) + expect(stderr).toMatch(/Built-in CSS support is being disabled/) + expect(stdout).toMatch(/Compiled successfully/) }) - describe('Bad CSS Customization', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration') + it(`should've applied style`, async () => { + const pagesFolder = join(appDir, '.next/static/chunks/pages') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + const files = await readdir(pagesFolder) + const indexFiles = files.filter((f) => /^index.+\.js$/.test(f)) - it('should compile successfully', async () => { - const { stdout, stderr } = await nextBuild(appDir, [], { - stdout: true, - stderr: true, - }) - expect(stdout).toMatch(/Compiled successfully/) - expect(stderr).toMatch(/field which is not supported.*?sourceMap/) - ;[ - 'postcss-modules-values', - 'postcss-modules-scope', - 'postcss-modules-extract-imports', - 'postcss-modules-local-by-default', - 'postcss-modules', - ].forEach((plugin) => { - expect(stderr).toMatch( - new RegExp(`Please remove the.*?${escapeStringRegexp(plugin)}`) - ) - }) - }) - - it(`should've compiled and prefixed`, async () => { - const cssFolder = join(appDir, '.next/static/css') + expect(indexFiles.length).toBe(1) + const indexContent = await readFile( + join(pagesFolder, indexFiles[0]), + 'utf8' + ) + expect(indexContent).toMatch(/\.my-text\.jsx-[0-9a-z]+{color:red}/) + }) + }) - const files = await readdir(cssFolder) - const cssFiles = files.filter((f) => /\.css$/.test(f)) + describe('Bad CSS Customization', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration') - expect(cssFiles.length).toBe(1) - const cssContent = await readFile( - join(cssFolder, cssFiles[0]), - 'utf8' - ) - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".video{max-width:400px;max-height:300px}"` - ) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - // Contains a source map - expect(cssContent).toMatch( - /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// + it('should compile successfully', async () => { + const { stdout, stderr } = await nextBuild(appDir, [], { + stdout: true, + stderr: true, + }) + expect(stdout).toMatch(/Compiled successfully/) + expect(stderr).toMatch(/field which is not supported.*?sourceMap/) + ;[ + 'postcss-modules-values', + 'postcss-modules-scope', + 'postcss-modules-extract-imports', + 'postcss-modules-local-by-default', + 'postcss-modules', + ].forEach((plugin) => { + expect(stderr).toMatch( + new RegExp(`Please remove the.*?${escapeStringRegexp(plugin)}`) ) }) + }) - it(`should've emitted a source map`, async () => { - const cssFolder = join(appDir, '.next/static/css') + it(`should've compiled and prefixed`, async () => { + const cssFolder = join(appDir, '.next/static/css') + + const files = await readdir(cssFolder) + const cssFiles = files.filter((f) => /\.css$/.test(f)) + + expect(cssFiles.length).toBe(1) + const cssContent = await readFile( + join(cssFolder, cssFiles[0]), + 'utf8' + ) + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".video{max-width:400px;max-height:300px}"`) + + // Contains a source map + expect(cssContent).toMatch( + /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// + ) + }) - const files = await readdir(cssFolder) - const cssMapFiles = files.filter((f) => /\.css\.map$/.test(f)) + it(`should've emitted a source map`, async () => { + const cssFolder = join(appDir, '.next/static/css') - expect(cssMapFiles.length).toBe(1) - }) + const files = await readdir(cssFolder) + const cssMapFiles = files.filter((f) => /\.css\.map$/.test(f)) + + expect(cssMapFiles.length).toBe(1) }) + }) - describe('Bad CSS Customization Array (1)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-1') + describe('Bad CSS Customization Array (1)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-1') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (2)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-2') + describe('Bad CSS Customization Array (2)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-2') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /Error: Your PostCSS configuration for 'postcss-trolling' cannot have null configuration./ - ) - expect(stderr).toMatch( - /To disable 'postcss-trolling', pass false, otherwise, pass true or a configuration object./ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /Error: Your PostCSS configuration for 'postcss-trolling' cannot have null configuration./ + ) + expect(stderr).toMatch( + /To disable 'postcss-trolling', pass false, otherwise, pass true or a configuration object./ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (3)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-3') + describe('Bad CSS Customization Array (3)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-3') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /A PostCSS Plugin must be provided as a string. Instead, we got: '5'/ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /A PostCSS Plugin must be provided as a string. Instead, we got: '5'/ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (4)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-4') + describe('Bad CSS Customization Array (4)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-4') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /An unknown PostCSS plugin was provided \(5\)/ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch(/An unknown PostCSS plugin was provided \(5\)/) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (5)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-5') + describe('Bad CSS Customization Array (5)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-5') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /Your custom PostCSS configuration must export a `plugins` key./ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /Your custom PostCSS configuration must export a `plugins` key./ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (6)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-6') + describe('Bad CSS Customization Array (6)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-6') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /Your custom PostCSS configuration must export a `plugins` key./ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /Your custom PostCSS configuration must export a `plugins` key./ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (7)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-7') + describe('Bad CSS Customization Array (7)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-7') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /A PostCSS Plugin was passed as an array but did not provide its configuration \('postcss-trolling'\)/ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Array (8)', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-arr-8') + describe('Bad CSS Customization Array (8)', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-arr-8') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /A PostCSS Plugin was passed as a function using require\(\), but it must be provided as a string/ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /A PostCSS Plugin was passed as a function using require\(\), but it must be provided as a string/ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) + }) - describe('Bad CSS Customization Function', () => { - const appDir = join(fixturesDir, 'bad-custom-configuration-func') + describe('Bad CSS Customization Function', () => { + const appDir = join(fixturesDir, 'bad-custom-configuration-func') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail the build', async () => { - const { stderr } = await nextBuild(appDir, [], { stderr: true }) + it('should fail the build', async () => { + const { stderr } = await nextBuild(appDir, [], { stderr: true }) - expect(stderr).toMatch( - /Your custom PostCSS configuration may not export a function/ - ) - expect(stderr).toMatch(BUILD_FAILURE_RE) - }) + expect(stderr).toMatch( + /Your custom PostCSS configuration may not export a function/ + ) + expect(stderr).toMatch(BUILD_FAILURE_RE) }) - } - ) + }) + }) } ) diff --git a/test/integration/css-features/test/browserslist.test.js b/test/integration/css-features/test/browserslist.test.js index b5cfaba07158d..61e6ad2b35cbd 100644 --- a/test/integration/css-features/test/browserslist.test.js +++ b/test/integration/css-features/test/browserslist.test.js @@ -15,109 +15,103 @@ import cheerio from 'cheerio' const fixturesDir = join(__dirname, '../fixtures') describe('Browserslist: Old', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'browsers-old') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir, [], { - stdout: true, - }) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) + describe('production mode', () => { + const appDir = join(fixturesDir, 'browsers-old') + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir, [], { + stdout: true, }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheetUrl = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheetUrl).then( - (res) => res.text() + if (code !== 0) { + throw new Error('Build failed') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheetUrl = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheetUrl).then( + (res) => res.text() + ) + + const cssContentWithoutSourceMap = cssContent + .replace(/\/\*.*?\*\/\n?/g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST) { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"a{all:initial}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` ) - - const cssContentWithoutSourceMap = cssContent - .replace(/\/\*.*?\*\/\n?/g, '') - .trim() - - if (process.env.IS_TURBOPACK_TEST) { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"a{all:initial}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` - ) - } else { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"a{-webkit-animation:none 0s ease 0s 1 normal none running;animation:none 0s ease 0s 1 normal none running;-webkit-backface-visibility:visible;backface-visibility:visible;background:transparent none repeat 0 0/auto auto padding-box border-box scroll;border:none;border-collapse:separate;-webkit-border-image:none;border-image:none;-webkit-border-radius:0;border-radius:0;border-spacing:0;bottom:auto;-webkit-box-shadow:none;box-shadow:none;-webkit-box-sizing:content-box;box-sizing:content-box;caption-side:top;clear:none;clip:auto;color:#000;-webkit-columns:auto;-webkit-column-count:auto;-webkit-column-fill:balance;column-fill:balance;-webkit-column-gap:normal;column-gap:normal;-webkit-column-rule:medium none currentColor;column-rule:medium none currentColor;-webkit-column-span:1;column-span:1;-webkit-column-width:auto;columns:auto;content:normal;counter-increment:none;counter-reset:none;cursor:auto;direction:ltr;display:inline;empty-cells:show;float:none;font-family:serif;font-size:medium;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;line-height:normal;height:auto;-ms-hyphens:none;hyphens:none;left:auto;letter-spacing:normal;list-style:disc none outside;margin:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;orphans:2;outline:medium none invert;overflow:visible;overflow-x:visible;overflow-y:visible;padding:0;page-break-after:auto;page-break-before:auto;page-break-inside:auto;-webkit-perspective:none;perspective:none;-webkit-perspective-origin:50% 50%;perspective-origin:50% 50%;position:static;right:auto;tab-size:8;table-layout:auto;text-align:left;text-align-last:auto;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;top:auto;-webkit-transform:none;transform:none;-webkit-transform-origin:50% 50% 0;transform-origin:50% 50% 0;-webkit-transform-style:flat;transform-style:flat;-webkit-transition:none 0s ease 0s;transition:none 0s ease 0s;unicode-bidi:normal;vertical-align:baseline;visibility:visible;white-space:normal;widows:2;width:auto;word-spacing:normal;z-index:auto;all:initial}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` - ) - } - }) - } - ) + } else { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"a{-webkit-animation:none 0s ease 0s 1 normal none running;animation:none 0s ease 0s 1 normal none running;-webkit-backface-visibility:visible;backface-visibility:visible;background:transparent none repeat 0 0/auto auto padding-box border-box scroll;border:none;border-collapse:separate;-webkit-border-image:none;border-image:none;-webkit-border-radius:0;border-radius:0;border-spacing:0;bottom:auto;-webkit-box-shadow:none;box-shadow:none;-webkit-box-sizing:content-box;box-sizing:content-box;caption-side:top;clear:none;clip:auto;color:#000;-webkit-columns:auto;-webkit-column-count:auto;-webkit-column-fill:balance;column-fill:balance;-webkit-column-gap:normal;column-gap:normal;-webkit-column-rule:medium none currentColor;column-rule:medium none currentColor;-webkit-column-span:1;column-span:1;-webkit-column-width:auto;columns:auto;content:normal;counter-increment:none;counter-reset:none;cursor:auto;direction:ltr;display:inline;empty-cells:show;float:none;font-family:serif;font-size:medium;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;line-height:normal;height:auto;-ms-hyphens:none;hyphens:none;left:auto;letter-spacing:normal;list-style:disc none outside;margin:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;orphans:2;outline:medium none invert;overflow:visible;overflow-x:visible;overflow-y:visible;padding:0;page-break-after:auto;page-break-before:auto;page-break-inside:auto;-webkit-perspective:none;perspective:none;-webkit-perspective-origin:50% 50%;perspective-origin:50% 50%;position:static;right:auto;tab-size:8;table-layout:auto;text-align:left;text-align-last:auto;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;top:auto;-webkit-transform:none;transform:none;-webkit-transform-origin:50% 50% 0;transform-origin:50% 50% 0;-webkit-transform-style:flat;transform-style:flat;-webkit-transition:none 0s ease 0s;transition:none 0s ease 0s;unicode-bidi:normal;vertical-align:baseline;visibility:visible;white-space:normal;widows:2;width:auto;word-spacing:normal;z-index:auto;all:initial}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` + ) + } + }) + }) }) describe('Browserslist: New', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'browsers-new') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir, [], { - stdout: true, - }) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) + describe('production mode', () => { + const appDir = join(fixturesDir, 'browsers-new') + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir, [], { + stdout: true, }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheetUrl = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheetUrl).then( - (res) => res.text() + if (code !== 0) { + throw new Error('Build failed') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheetUrl = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheetUrl).then( + (res) => res.text() + ) + + const cssContentWithoutSourceMap = cssContent + .replace(/\/\*.*?\*\/\n?/g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST) { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"a{all:initial}@media (resolution>=2x){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` ) - - const cssContentWithoutSourceMap = cssContent - .replace(/\/\*.*?\*\/\n?/g, '') - .trim() - - if (process.env.IS_TURBOPACK_TEST) { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"a{all:initial}@media (resolution>=2x){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` - ) - } else { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"a{all:initial}@media (min-resolution:2dppx){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` - ) - } - }) - } - ) + } else { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"a{all:initial}@media (min-resolution:2dppx){.image{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}}"` + ) + } + }) + }) }) diff --git a/test/integration/css-features/test/css-modules.test.js b/test/integration/css-features/test/css-modules.test.js index 2a8bb210d1970..687d91b4246e8 100644 --- a/test/integration/css-features/test/css-modules.test.js +++ b/test/integration/css-features/test/css-modules.test.js @@ -18,62 +18,130 @@ const fixturesDir = join(__dirname, '../fixtures') ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( 'Custom Properties: Fail for :root {} in CSS Modules', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'cp-global-modules') + describe('production mode', () => { + const appDir = join(fixturesDir, 'cp-global-modules') - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - it('should fail to build', async () => { - const { code, stderr } = await nextBuild(appDir, [], { - stderr: true, - }) - expect(code).not.toBe(0) - expect(stderr).toContain('Failed to compile') - expect(stderr).toContain('pages/styles.module.css') - expect(stderr).toContain('Selector ":root" is not pure') + it('should fail to build', async () => { + const { code, stderr } = await nextBuild(appDir, [], { + stderr: true, }) - } - ) + expect(code).not.toBe(0) + expect(stderr).toContain('Failed to compile') + expect(stderr).toContain('pages/styles.module.css') + expect(stderr).toContain('Selector ":root" is not pure') + }) + }) } ) describe('Custom Properties: Fail for global element in CSS Modules', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'cp-el-modules') + describe('production mode', () => { + const appDir = join(fixturesDir, 'cp-el-modules') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + it('should fail to build', async () => { + const { code, stderr } = await nextBuild(appDir, [], { + stderr: true, + }) + expect(code).not.toBe(0) + if (process.env.IS_TURBOPACK_TEST) { + expect(stderr).toContain('pages/styles.module.css') + expect(stderr).toContain('Selector "h1" is not pure') + } else { + expect(stderr).toContain('Failed to compile') + expect(stderr).toContain('pages/styles.module.css') + expect(stderr).toContain('Selector "h1" is not pure') + } + }) + }) +}) + +describe('CSS Modules: Import Global CSS', () => { + describe('production mode', () => { + const appDir = join(fixturesDir, 'module-import-global') + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('failed to build') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheet = cssSheet.attr('href') + + const cssContent = ( + await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) + ) + .replace(/\/\*.*?\*\//g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`"a .foo{all:initial}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`"a .styles_foo__G5630{all:initial}"`) + } + }) + }) +}) +// Disabled with Turbopack because importing `.css` files in `.module.css` is handled as `.css` file not `.module.css` file +;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'CSS Modules: Importing Invalid Global CSS', + () => { + // eslint-disable-next-line jest/no-identical-title + describe('production mode', () => { + const appDir = join(fixturesDir, 'module-import-global-invalid') beforeAll(async () => { await remove(join(appDir, '.next')) }) + // eslint-disable-next-line jest/no-identical-title it('should fail to build', async () => { const { code, stderr } = await nextBuild(appDir, [], { stderr: true, }) expect(code).not.toBe(0) - if (process.env.IS_TURBOPACK_TEST) { - expect(stderr).toContain('pages/styles.module.css') - expect(stderr).toContain('Selector "h1" is not pure') - } else { - expect(stderr).toContain('Failed to compile') - expect(stderr).toContain('pages/styles.module.css') - expect(stderr).toContain('Selector "h1" is not pure') - } + expect(stderr).toContain('Failed to compile') + expect(stderr).toContain('pages/styles.css') + expect(stderr).toContain('Selector "a" is not pure') }) - } - ) -}) + }) + } +) -describe('CSS Modules: Import Global CSS', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'module-import-global') +// Turbopack uses LightningCSS which doesn't support `@value`. +;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'CSS Modules: Import Exports', + () => { + // eslint-disable-next-line jest/no-identical-title + describe('production mode', () => { + const appDir = join(fixturesDir, 'module-import-exports') let appPort let app @@ -105,91 +173,10 @@ describe('CSS Modules: Import Global CSS', () => { .replace(/\/\*.*?\*\//g, '') .trim() - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`"a .foo{all:initial}"`) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`"a .styles_foo__G5630{all:initial}"`) - } + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".styles_blk__480DC{color:#000000}"`) }) - } - ) -}) -// Disabled with Turbopack because importing `.css` files in `.module.css` is handled as `.css` file not `.module.css` file -;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'CSS Modules: Importing Invalid Global CSS', - () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'module-import-global-invalid') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - - // eslint-disable-next-line jest/no-identical-title - it('should fail to build', async () => { - const { code, stderr } = await nextBuild(appDir, [], { - stderr: true, - }) - expect(code).not.toBe(0) - expect(stderr).toContain('Failed to compile') - expect(stderr).toContain('pages/styles.css') - expect(stderr).toContain('Selector "a" is not pure') - }) - } - ) - } -) - -// Turbopack uses LightningCSS which doesn't support `@value`. -;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'CSS Modules: Import Exports', - () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'module-import-exports') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('failed to build') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheet = cssSheet.attr('href') - - const cssContent = ( - await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) - ) - .replace(/\/\*.*?\*\//g, '') - .trim() - - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`".styles_blk__480DC{color:#000000}"`) - }) - } - ) + }) } ) diff --git a/test/integration/css-features/test/index.test.js b/test/integration/css-features/test/index.test.js index c28f2f9f8f732..08c23c0895ae5 100644 --- a/test/integration/css-features/test/index.test.js +++ b/test/integration/css-features/test/index.test.js @@ -16,60 +16,105 @@ import { join } from 'path' const fixturesDir = join(__dirname, '../fixtures') describe('Custom Properties: Pass-Through IE11', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'cp-ie-11') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('failed to build') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheet = cssSheet.attr('href') - - const cssContent = ( - await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) - ) - .replace(/\/\*.*?\*\//g, '') - .trim() - - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) - } - }) - } - ) + describe('production mode', () => { + const appDir = join(fixturesDir, 'cp-ie-11') + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('failed to build') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheet = cssSheet.attr('href') + + const cssContent = ( + await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) + ) + .replace(/\/\*.*?\*\//g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) + } + }) + }) }) describe('Custom Properties: Pass-Through Modern', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'cp-modern') + describe('production mode', () => { + const appDir = join(fixturesDir, 'cp-modern') + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('failed to build') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheet = cssSheet.attr('href') + + const cssContent = ( + await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) + ) + .replace(/\/\*.*?\*\//g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) + } + }) + }) +}) + +// This is checking invalid CSS that Lightning CSS in Turbopack interprets differently. Since it's invalid syntax it's documented as unsupported. +;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'Inline Comments: Minify', + () => { + describe('production mode', () => { + const appDir = join(fixturesDir, 'inline-comments') let appPort let app @@ -104,67 +149,13 @@ describe('Custom Properties: Pass-Through Modern', () => { if (process.env.IS_TURBOPACK_TEST) { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) + ).toMatchInlineSnapshot(`""`) } else { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`":root{--color:red}h1{color:var(--color)}"`) + ).toMatchInlineSnapshot(`"*{box-sizing:border-box}"`) } }) - } - ) -}) - -// This is checking invalid CSS that Lightning CSS in Turbopack interprets differently. Since it's invalid syntax it's documented as unsupported. -;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'Inline Comments: Minify', - () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'inline-comments') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('failed to build') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheet = cssSheet.attr('href') - - const cssContent = ( - await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) - ) - .replace(/\/\*.*?\*\//g, '') - .trim() - - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`""`) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`"*{box-sizing:border-box}"`) - } - }) - } - ) + }) } ) diff --git a/test/integration/css-minify/test/index.test.js b/test/integration/css-minify/test/index.test.js index a6442592f5a41..4241e98fed7c4 100644 --- a/test/integration/css-minify/test/index.test.js +++ b/test/integration/css-minify/test/index.test.js @@ -33,18 +33,15 @@ function runTests() { } describe('css-minify', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - runTests() - } - ) + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + runTests() + }) }) diff --git a/test/integration/css-modules/test/index.test.js b/test/integration/css-modules/test/index.test.js index 0626a3399b488..6773ced4bd694 100644 --- a/test/integration/css-modules/test/index.test.js +++ b/test/integration/css-modules/test/index.test.js @@ -19,159 +19,153 @@ import { join } from 'path' const fixturesDir = join(__dirname, '../../css-fixtures') describe('Basic CSS Module Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'basic-module') + describe('production mode', () => { + const appDir = join(fixturesDir, 'basic-module') + + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + expect(stdout).toContain('.css') + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + const stylesheet = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => + res.text() + ) - let appPort - let app - let stdout - let code - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".index-module__VJHdSq__redText{color:red}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".index_redText__honUV{color:red}"`) + } + }) - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - expect(stdout).toContain('.css') - }) + it(`should've injected the CSS on server render`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + const cssPreload = $('link[rel="preload"][as="style"]') + expect(cssPreload.length).toBe(1) + expect(cssPreload.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - const stylesheet = cssSheet.attr('href') + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + expect(cssSheet.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) - const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => - res.text() + if (process.env.IS_TURBOPACK_TEST) { + expect($('#verify-red').attr('class')).toMatchInlineSnapshot( + `"index-module__VJHdSq__redText"` ) - - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`".index-module__VJHdSq__redText{color:red}"`) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`".index_redText__honUV{color:red}"`) - } - }) - - it(`should've injected the CSS on server render`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssPreload = $('link[rel="preload"][as="style"]') - expect(cssPreload.length).toBe(1) - expect(cssPreload.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - expect(cssSheet.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) - - if (process.env.IS_TURBOPACK_TEST) { - expect($('#verify-red').attr('class')).toMatchInlineSnapshot( - `"index-module__VJHdSq__redText"` - ) - } else { - expect($('#verify-red').attr('class')).toMatchInlineSnapshot( - `"index_redText__honUV"` - ) - } - }) - } - ) + } else { + expect($('#verify-red').attr('class')).toMatchInlineSnapshot( + `"index_redText__honUV"` + ) + } + }) + }) }) describe('3rd Party CSS Module Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, '3rd-party-module') - - let appPort - let app - let stdout - let code - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - const stylesheet = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => - res.text() + describe('production mode', () => { + const appDir = join(fixturesDir, '3rd-party-module') + + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + const stylesheet = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => + res.text() + ) + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `".index-module__jAE1EW__foo{position:relative}.index-module__jAE1EW__foo .bar{height:100%;overflow:hidden}.index-module__jAE1EW__foo .baz{height:100%;overflow:hidden}.index-module__jAE1EW__foo .lol{width:80%}.index-module__jAE1EW__foo>.lel{width:80%}"` ) - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".index-module__jAE1EW__foo{position:relative}.index-module__jAE1EW__foo .bar{height:100%;overflow:hidden}.index-module__jAE1EW__foo .baz{height:100%;overflow:hidden}.index-module__jAE1EW__foo .lol{width:80%}.index-module__jAE1EW__foo>.lel{width:80%}"` - ) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".index_foo__6TgnK{position:relative}.index_foo__6TgnK .bar,.index_foo__6TgnK .baz{height:100%;overflow:hidden}.index_foo__6TgnK .lol,.index_foo__6TgnK>.lel{width:80%}"` - ) - } - }) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `".index_foo__6TgnK{position:relative}.index_foo__6TgnK .bar,.index_foo__6TgnK .baz{height:100%;overflow:hidden}.index_foo__6TgnK .lol,.index_foo__6TgnK>.lel{width:80%}"` + ) + } + }) - it(`should've injected the CSS on server render`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've injected the CSS on server render`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssPreload = $('link[rel="preload"][as="style"]') - expect(cssPreload.length).toBe(1) - expect(cssPreload.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) + const cssPreload = $('link[rel="preload"][as="style"]') + expect(cssPreload.length).toBe(1) + expect(cssPreload.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - expect(cssSheet.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + expect(cssSheet.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) - if (process.env.IS_TURBOPACK_TEST) { - expect($('#verify-div').attr('class')).toMatchInlineSnapshot( - `"index-module__jAE1EW__foo"` - ) - } else { - expect($('#verify-div').attr('class')).toMatchInlineSnapshot( - `"index_foo__6TgnK"` - ) - } - }) - } - ) + if (process.env.IS_TURBOPACK_TEST) { + expect($('#verify-div').attr('class')).toMatchInlineSnapshot( + `"index-module__jAE1EW__foo"` + ) + } else { + expect($('#verify-div').attr('class')).toMatchInlineSnapshot( + `"index_foo__6TgnK"` + ) + } + }) + }) }) describe('Has CSS Module in computed styles in Development', () => { @@ -199,42 +193,39 @@ describe('Has CSS Module in computed styles in Development', () => { }) describe('Has CSS Module in computed styles in Production', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'prod-module') - - let appPort - let app - let stdout - let code - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) - - it('should have CSS for page', async () => { - const browser = await webdriver(appPort, '/') - - const currentColor = await browser.eval( - `window.getComputedStyle(document.querySelector('#verify-red')).color` - ) - expect(currentColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`) - }) - } - ) + describe('production mode', () => { + const appDir = join(fixturesDir, 'prod-module') + + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) + + it('should have CSS for page', async () => { + const browser = await webdriver(appPort, '/') + + const currentColor = await browser.eval( + `window.getComputedStyle(document.querySelector('#verify-red')).color` + ) + expect(currentColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`) + }) + }) }) describe('Can hot reload CSS Module without losing state', () => { @@ -284,86 +275,151 @@ describe('Can hot reload CSS Module without losing state', () => { }) describe.skip('Invalid CSS Module Usage in node_modules', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'invalid-module') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - - it('should fail to build', async () => { - const { code, stderr } = await nextBuild(appDir, [], { - stderr: true, - }) - expect(code).not.toBe(0) - expect(stderr).toContain('Failed to compile') - expect(stderr).toContain('node_modules/example/index.module.css') + describe('production mode', () => { + const appDir = join(fixturesDir, 'invalid-module') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + it('should fail to build', async () => { + const { code, stderr } = await nextBuild(appDir, [], { + stderr: true, + }) + expect(code).not.toBe(0) + expect(stderr).toContain('Failed to compile') + expect(stderr).toContain('node_modules/example/index.module.css') + expect(stderr).toMatch( + /CSS Modules.*cannot.*be imported from within.*node_modules/ + ) + // Skip: Rspack loaders cannot access module issuer info for location details + if (!process.env.NEXT_RSPACK) { expect(stderr).toMatch( - /CSS Modules.*cannot.*be imported from within.*node_modules/ + /Location:.*node_modules[\\/]example[\\/]index\.mjs/ ) - // Skip: Rspack loaders cannot access module issuer info for location details - if (!process.env.NEXT_RSPACK) { - expect(stderr).toMatch( - /Location:.*node_modules[\\/]example[\\/]index\.mjs/ - ) - } - }) - } - ) + } + }) + }) }) describe.skip('Invalid Global CSS Module Usage in node_modules', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'invalid-global-module') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - - it('should fail to build', async () => { - const { code, stderr } = await nextBuild(appDir, [], { - stderr: true, - }) - expect(code).not.toBe(0) - expect(stderr).toContain('Failed to compile') - expect(stderr).toContain('node_modules/example/index.css') + describe('production mode', () => { + const appDir = join(fixturesDir, 'invalid-global-module') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + it('should fail to build', async () => { + const { code, stderr } = await nextBuild(appDir, [], { + stderr: true, + }) + expect(code).not.toBe(0) + expect(stderr).toContain('Failed to compile') + expect(stderr).toContain('node_modules/example/index.css') + expect(stderr).toMatch( + /Global CSS.*cannot.*be imported from within.*node_modules/ + ) + // Skip: Rspack loaders cannot access module issuer info for location details + if (!process.env.NEXT_RSPACK) { expect(stderr).toMatch( - /Global CSS.*cannot.*be imported from within.*node_modules/ + /Location:.*node_modules[\\/]example[\\/]index\.mjs/ ) - // Skip: Rspack loaders cannot access module issuer info for location details - if (!process.env.NEXT_RSPACK) { - expect(stderr).toMatch( - /Location:.*node_modules[\\/]example[\\/]index\.mjs/ - ) - } - }) - } - ) + } + }) + }) }) describe('Valid CSS Module Usage from within node_modules', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'nm-module') + describe('production mode', () => { + const appDir = join(fixturesDir, 'nm-module') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) + + it(`should've prerendered with relevant data`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssPreload = $('#nm-div') + if (process.env.IS_TURBOPACK_TEST) { + expect(cssPreload.text()).toMatchInlineSnapshot( + `"{"message":"Why hello there","default":{"message":"Why hello there"}} {"redText":"index-module__kwuKnq__redText","default":{"redText":"index-module__kwuKnq__redText"}}"` + ) + } else { + expect(cssPreload.text()).toMatchInlineSnapshot( + `"{"message":"Why hello there"} {"redText":"example_redText__0ctGB"}"` + ) + } + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + const stylesheet = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => + res.text() + ) + + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".index-module__kwuKnq__redText{color:red}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".example_redText__0ctGB{color:red}"`) + } + }) + }) +}) + +// Disabled with Turbopack because `composes` from `.css` files in `.module.css` files is not supported. +;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'Valid Nested CSS Module Usage from within node_modules', + () => { + describe('production mode', () => { + const appDir = join(fixturesDir, 'nm-module-nested') let appPort let app - let stdout - let code beforeAll(async () => { await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { + const { code, stdout } = await nextBuild(appDir, [], { stdout: true, - })) + }) + + if (code !== 0) { + console.error(stdout) + throw new Error('Build failed') + } + appPort = await findPort() app = await nextStart(appDir, appPort) }) @@ -371,27 +427,18 @@ describe('Valid CSS Module Usage from within node_modules', () => { await killApp(app) }) - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) - + // eslint-disable-next-line jest/no-identical-title it(`should've prerendered with relevant data`, async () => { const content = await renderViaHTTP(appPort, '/') const $ = cheerio.load(content) const cssPreload = $('#nm-div') - if (process.env.IS_TURBOPACK_TEST) { - expect(cssPreload.text()).toMatchInlineSnapshot( - `"{"message":"Why hello there","default":{"message":"Why hello there"}} {"redText":"index-module__kwuKnq__redText","default":{"redText":"index-module__kwuKnq__redText"}}"` - ) - } else { - expect(cssPreload.text()).toMatchInlineSnapshot( - `"{"message":"Why hello there"} {"redText":"example_redText__0ctGB"}"` - ) - } + expect(cssPreload.text()).toMatchInlineSnapshot( + `"{"message":"Why hello there"} {"subClass":"example_subClass__m6Tyy other_className__OA8dV"}"` + ) }) + // eslint-disable-next-line jest/no-identical-title it(`should've emitted a single CSS file`, async () => { const content = await renderViaHTTP(appPort, '/') const $ = cheerio.load(content) @@ -407,105 +454,95 @@ describe('Valid CSS Module Usage from within node_modules', () => { if (process.env.IS_TURBOPACK_TEST) { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`".index-module__kwuKnq__redText{color:red}"`) + ).toMatchInlineSnapshot( + `".other2_other2__dYPgz{color:red}.other3_other3__7hgUE{color:violet}.other_className__OA8dV{background:red;color:#ff0}.example_subClass__m6Tyy{background:blue}"` + ) } else { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`".example_redText__0ctGB{color:red}"`) + ).toMatchInlineSnapshot( + `".other2_other2__dYPgz{color:red}.other3_other3__7hgUE{color:violet}.other_className__OA8dV{background:red;color:yellow}.example_subClass__m6Tyy{background:blue}"` + ) } }) - } - ) -}) - -// Disabled with Turbopack because `composes` from `.css` files in `.module.css` files is not supported. -;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'Valid Nested CSS Module Usage from within node_modules', - () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'nm-module-nested') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code, stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - - if (code !== 0) { - console.error(stdout) - throw new Error('Build failed') - } - - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - // eslint-disable-next-line jest/no-identical-title - it(`should've prerendered with relevant data`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssPreload = $('#nm-div') - expect(cssPreload.text()).toMatchInlineSnapshot( - `"{"message":"Why hello there"} {"subClass":"example_subClass__m6Tyy other_className__OA8dV"}"` - ) - }) - - // eslint-disable-next-line jest/no-identical-title - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - const stylesheet = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheet).then( - (res) => res.text() - ) - - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".other2_other2__dYPgz{color:red}.other3_other3__7hgUE{color:violet}.other_className__OA8dV{background:red;color:#ff0}.example_subClass__m6Tyy{background:blue}"` - ) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".other2_other2__dYPgz{color:red}.other3_other3__7hgUE{color:violet}.other_className__OA8dV{background:red;color:yellow}.example_subClass__m6Tyy{background:blue}"` - ) - } - }) - } - ) + }) } ) describe('CSS Module Composes Usage (Basic)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { + describe('production mode', () => { + // This is a very bad feature. Do not use it. + const appDir = join(fixturesDir, 'composes-basic') + + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + const stylesheet = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => + res.text() + ) + + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `".index-module__QppuLW__className{color:#ff0;background:red}.index-module__QppuLW__subClass{background:#00f;}"` + ) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `".index_className__jjcZ1{background:red;color:yellow}.index_subClass__eDzaW{background:blue}"` + ) + } + }) + }) +}) +;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + 'CSS Module Composes Usage (External)', + () => { + // eslint-disable-next-line jest/no-identical-title + describe('production mode', () => { // This is a very bad feature. Do not use it. - const appDir = join(fixturesDir, 'composes-basic') + const appDir = join(fixturesDir, 'composes-external') let appPort let app - let stdout - let code beforeAll(async () => { await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { + console.log({ appDir }) + const { code, stdout } = await nextBuild(appDir, [], { stdout: true, - })) + }) + if (code !== 0) { + console.error(stdout) + throw new Error('Build failed') + } appPort = await findPort() app = await nextStart(appDir, appPort) }) @@ -513,11 +550,7 @@ describe('CSS Module Composes Usage (Basic)', () => { await killApp(app) }) - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) - + // eslint-disable-next-line jest/no-identical-title it(`should've emitted a single CSS file`, async () => { const content = await renderViaHTTP(appPort, '/') const $ = cheerio.load(content) @@ -534,208 +567,141 @@ describe('CSS Module Composes Usage (Basic)', () => { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() ).toMatchInlineSnapshot( - `".index-module__QppuLW__className{color:#ff0;background:red}.index-module__QppuLW__subClass{background:#00f;}"` + `".other_className__eZV4M{background:red;color:#ff0}.index_subClass__eDzaW{background:blue}"` ) } else { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() ).toMatchInlineSnapshot( - `".index_className__jjcZ1{background:red;color:yellow}.index_subClass__eDzaW{background:blue}"` + `".other_className__eZV4M{background:red;color:yellow}.index_subClass__eDzaW{background:blue}"` ) } }) - } - ) -}) -;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - 'CSS Module Composes Usage (External)', - () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - // This is a very bad feature. Do not use it. - const appDir = join(fixturesDir, 'composes-external') - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - console.log({ appDir }) - const { code, stdout } = await nextBuild(appDir, [], { - stdout: true, - }) - if (code !== 0) { - console.error(stdout) - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - // eslint-disable-next-line jest/no-identical-title - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - const stylesheet = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheet).then( - (res) => res.text() - ) - - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".other_className__eZV4M{background:red;color:#ff0}.index_subClass__eDzaW{background:blue}"` - ) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".other_className__eZV4M{background:red;color:yellow}.index_subClass__eDzaW{background:blue}"` - ) - } - }) - } - ) + }) } ) describe('Dynamic Route CSS Module Usage', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'dynamic-route-module') - - let stdout - let code - let app - let appPort - - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) - - it('should apply styles correctly', async () => { - const browser = await webdriver(appPort, '/post-1') - - const background = await browser - .elementByCss('#my-div') - .getComputedCss('background-color') - - expect(background).toMatch(/rgb(a|)\(255, 0, 0/) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/post-1') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - const stylesheet = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => - res.text() - ) - if (process.env.IS_TURBOPACK_TEST) { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".index-module__Iury9a__home{background:red}"` - ) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot(`"._post__home__yRmHz{background:#f00}"`) - } - }) - } - ) + describe('production mode', () => { + const appDir = join(fixturesDir, 'dynamic-route-module') + + let stdout + let code + let app + let appPort + + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) + + it('should apply styles correctly', async () => { + const browser = await webdriver(appPort, '/post-1') + + const background = await browser + .elementByCss('#my-div') + .getComputedCss('background-color') + + expect(background).toMatch(/rgb(a|)\(255, 0, 0/) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/post-1') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + const stylesheet = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => + res.text() + ) + if (process.env.IS_TURBOPACK_TEST) { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`".index-module__Iury9a__home{background:red}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot(`"._post__home__yRmHz{background:#f00}"`) + } + }) + }) }) describe('Catch-all Route CSS Module Usage', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'catch-all-module') - - let stdout - let code - let app - let appPort - - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(app)) - - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) - - it('should apply styles correctly', async () => { - const browser = await webdriver(appPort, '/post-1') - - const bg = await browser - .elementByCss('#my-div') - .getComputedCss('background-color') - expect(bg).toMatch(/rgb(a|)\(255, 0, 0/) - - const fg = await browser.elementByCss('#my-div').getComputedCss('color') - expect(fg).toMatch(/rgb(a|)\(0, 128, 0/) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/post-1') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - const stylesheet = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => - res.text() - ) + describe('production mode', () => { + const appDir = join(fixturesDir, 'catch-all-module') + + let stdout + let code + let app + let appPort + + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) + + it('should apply styles correctly', async () => { + const browser = await webdriver(appPort, '/post-1') + + const bg = await browser + .elementByCss('#my-div') + .getComputedCss('background-color') + expect(bg).toMatch(/rgb(a|)\(255, 0, 0/) + + const fg = await browser.elementByCss('#my-div').getComputedCss('color') + expect(fg).toMatch(/rgb(a|)\(0, 128, 0/) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/post-1') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + const stylesheet = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheet).then((res) => + res.text() + ) - if (process.env.IS_TURBOPACK_TEST) { - expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()) - .toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST) { + expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()) + .toMatchInlineSnapshot(` ".index-module___rV4CG__home{background:red} .\\35 5css-module__qe774W__home{color:green}" `) - } else { - expect( - cssContent.replace(/\/\*.*?\*\//g, '').trim() - ).toMatchInlineSnapshot( - `".___post__home__e4zfx{background:#f00}.__55css_home__r8Rnq{color:green}"` - ) - } - }) - } - ) + } else { + expect( + cssContent.replace(/\/\*.*?\*\//g, '').trim() + ).toMatchInlineSnapshot( + `".___post__home__e4zfx{background:#f00}.__55css_home__r8Rnq{color:green}"` + ) + } + }) + }) }) describe('cssmodules-pure-no-check usage', () => { diff --git a/test/integration/css/test/basic-global-support.test.js b/test/integration/css/test/basic-global-support.test.js index 1b04600ca176a..8dd56fcfd3244 100644 --- a/test/integration/css/test/basic-global-support.test.js +++ b/test/integration/css/test/basic-global-support.test.js @@ -15,18 +15,16 @@ import { join } from 'path' const fixturesDir = join(__dirname, '../..', 'css-fixtures') describe('Basic Global Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'single-global') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'single-global') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -34,83 +32,76 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}", ] `) - } - }) + } }) - } - ) + }) + }) }) describe('Basic Global Support with special characters in path', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join( - fixturesDir, - 'single-global-special-characters', - 'a+b' - ) - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'single-global-special-characters', 'a+b') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../../next.config.js'); module.exports = { ...config, @@ -118,79 +109,76 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}", ] `) - } - }) + } }) - } - ) + }) + }) }) describe('Basic Global Support with src/ dir', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'single-global-src') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'single-global-src') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -198,78 +186,75 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) - - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } - - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - - afterAll(async () => { - await killApp(app) - }) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) - - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + ) + }) + + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } + + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + + afterAll(async () => { + await killApp(app) + }) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) + + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}", ] `) - } - }) + } }) - } - ) + }) + }) }) describe('Multi Global Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'multi-global') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'multi-global') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -277,81 +262,78 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red} .blue-text{color:#00f}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red} .blue-text{color:#00f}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}.blue-text{color:#00f}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red}.blue-text{color:blue}", ] `) - } - }) + } }) - } - ) + }) + }) }) describe('Nested @import() Global Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'nested-global') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'nested-global') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -359,33 +341,33 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:purple;font-weight:bolder} @@ -394,8 +376,8 @@ module.exports = { .blue-text{color:#00f}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:purple;font-weight:bolder} @@ -404,41 +386,38 @@ module.exports = { .blue-text{color:#00f}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:purple;font-weight:bolder;color:red}.blue-text{color:orange;font-weight:bolder;color:#00f}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:purple;font-weight:bolder;color:red}.blue-text{color:orange;font-weight:bolder;color:blue}", ] `) - } - }) + } }) - } - ) + }) + }) }) // Tests css ordering describe('Multi Global Support (reversed)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'multi-global-reversed') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'multi-global-reversed') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -446,81 +425,78 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .blue-text{color:#00f} .red-text{color:red}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .blue-text{color:#00f} .red-text{color:red}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .blue-text{color:#00f}.red-text{color:red}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .blue-text{color:blue}.red-text{color:red}", ] `) - } - }) + } }) - } - ) + }) + }) }) describe('CSS URL via `file-loader`', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'url-global') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'url-global') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -528,33 +504,33 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) - afterAll(async () => { - await killApp(app) - }) + afterAll(async () => { + await killApp(app) + }) - it(`should've emitted expected files`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) + it(`should've emitted expected files`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red;background-image:url(../media/dark.8425d343.svg),url(../media/dark2.8425d343.svg)} @@ -562,8 +538,8 @@ module.exports = { .blue-text{color:#00f}", ] `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red;background-image:url(../media/dark.8425d343.svg),url(../media/dark2.8425d343.svg)} @@ -571,59 +547,56 @@ module.exports = { .blue-text{color:#00f}", ] `) - } else if (useLightningcss) { - expect(cssContent).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red;background-image:url(/_next/static/media/dark.6b01655b.svg),url(/_next/static/media/dark2.6b01655b.svg)}.blue-text{color:orange;background-image:url(/_next/static/media/light.2da1d3d6.svg);font-weight:bolder;color:#00f}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red;background-image:url(/_next/static/media/dark.6b01655b.svg),url(/_next/static/media/dark2.6b01655b.svg)}.blue-text{color:orange;font-weight:bolder;background-image:url(/_next/static/media/light.2da1d3d6.svg);color:blue}", ] `) - } - }) + } }) - } - ) + }) + }) }) describe('CSS URL via `file-loader` and asset prefix (1)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'url-global-asset-prefix-1') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } - - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted expected files`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) - - if (process.env.IS_TURBOPACK_TEST) { - expect(cssContent).toMatchInlineSnapshot(` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'url-global-asset-prefix-1') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } + + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted expected files`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) + + if (process.env.IS_TURBOPACK_TEST) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red;background-image:url(../media/dark.8425d343.svg) url(../media/dark2.8425d343.svg)} @@ -631,51 +604,48 @@ describe('CSS URL via `file-loader` and asset prefix (1)', () => { .blue-text{color:#00f}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red;background-image:url(/foo/_next/static/media/dark.6b01655b.svg) url(/foo/_next/static/media/dark2.6b01655b.svg)}.blue-text{color:orange;font-weight:bolder;background-image:url(/foo/_next/static/media/light.2da1d3d6.svg);color:blue}", ] `) - } - }) - } - ) + } + }) + }) }) describe('CSS URL via `file-loader` and asset prefix (2)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let appPort - let app - const appDir = join(fixturesDir, 'url-global-asset-prefix-2') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Failed to build') - } - - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted expected files`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - const cssContent = await getStylesheetContents($, appPort, cssSheet) - - if (process.env.IS_TURBOPACK_TEST) { - expect(cssContent).toMatchInlineSnapshot(` + describe('production mode', () => { + let appPort + let app + const appDir = join(fixturesDir, 'url-global-asset-prefix-2') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Failed to build') + } + + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted expected files`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + const cssContent = await getStylesheetContents($, appPort, cssSheet) + + if (process.env.IS_TURBOPACK_TEST) { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/chunks/HASH.css: .red-text{color:red;background-image:url(../media/dark.8425d343.svg) url(../media/dark2.8425d343.svg)} @@ -683,17 +653,16 @@ describe('CSS URL via `file-loader` and asset prefix (2)', () => { .blue-text{color:#00f}", ] `) - } else { - expect(cssContent).toMatchInlineSnapshot(` + } else { + expect(cssContent).toMatchInlineSnapshot(` [ "/_next/static/css/HASH.css: .red-text{color:red;background-image:url(/foo/_next/static/media/dark.6b01655b.svg) url(/foo/_next/static/media/dark2.6b01655b.svg)}.blue-text{color:orange;font-weight:bolder;background-image:url(/foo/_next/static/media/light.2da1d3d6.svg);color:blue}", ] `) - } - }) - } - ) + } + }) + }) }) async function getStylesheetContents($, appPort, items) { diff --git a/test/integration/css/test/css-and-styled-jsx.test.js b/test/integration/css/test/css-and-styled-jsx.test.js index 041dbbafbe152..f641ea79519fa 100644 --- a/test/integration/css/test/css-and-styled-jsx.test.js +++ b/test/integration/css/test/css-and-styled-jsx.test.js @@ -37,40 +37,37 @@ describe('Ordering with styled-jsx (dev)', () => { }) describe('Ordering with styled-jsx (prod)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'with-styled-jsx') + describe('production mode', () => { + const appDir = join(fixturesDir, 'with-styled-jsx') - let appPort - let app - let stdout - let code - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) - it('should have the correct color (css ordering)', async () => { - const browser = await webdriver(appPort, '/') + it('should have the correct color (css ordering)', async () => { + const browser = await webdriver(appPort, '/') - const currentColor = await browser.eval( - `window.getComputedStyle(document.querySelector('.my-text')).color` - ) - expect(currentColor).toMatchInlineSnapshot(`"rgb(0, 128, 0)"`) - }) - } - ) + const currentColor = await browser.eval( + `window.getComputedStyle(document.querySelector('.my-text')).color` + ) + expect(currentColor).toMatchInlineSnapshot(`"rgb(0, 128, 0)"`) + }) + }) }) diff --git a/test/integration/css/test/css-compilation.test.js b/test/integration/css/test/css-compilation.test.js index 35fb8d079071a..a5f81c2411847 100644 --- a/test/integration/css/test/css-compilation.test.js +++ b/test/integration/css/test/css-compilation.test.js @@ -16,25 +16,21 @@ import { join } from 'path' const fixturesDir = join(__dirname, '../..', 'css-fixtures') describe('CSS Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - describe('CSS Compilation and Prefixing', () => { - const appDir = join(fixturesDir, 'compilation-and-prefixing') - const nextConfig = new File(join(appDir, 'next.config.js')) + describe('production mode', () => { + describe('CSS Compilation and Prefixing', () => { + const appDir = join(fixturesDir, 'compilation-and-prefixing') + const nextConfig = new File(join(appDir, 'next.config.js')) - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - describe.each([true, false])( - `useLightnincsss(%s)`, - (useLightningcss) => { - let appPort - let app - beforeAll(async () => { - nextConfig.write( - ` + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + let appPort + let app + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -42,83 +38,83 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - afterAll(async () => { - nextConfig.delete() - }) - - it(`should've compiled and prefixed`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheetUrl = cssSheet.attr('href') - - const cssContent = await fetchViaHTTP( - appPort, - stylesheetUrl - ).then((res) => res.text()) - - const cssContentWithoutSourceMap = cssContent - .replace(/\/\*.*?\*\/\n?/g, '') - .trim() - - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0px,0px)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` - ) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0px,0px)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` - ) - } else if (useLightningcss) { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0,0)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` - ) - } else { - expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"@media (min-width:480px) and (max-width:767px){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0,0)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:80%}"` - ) - } - - // Contains a source map - expect(cssContent).toMatch( - /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// - ) - - const sourceMapUrl = - /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\//.exec(cssContent)[1] - const actualSourceMapUrl = stylesheetUrl.replace( - /[^/]+$/, - sourceMapUrl - ) - - const sourceMapContent = await fetchViaHTTP( - appPort, - actualSourceMapUrl - ).then((res) => res.text()) - const sourceMapContentParsed = JSON.parse(sourceMapContent) - // Ensure it doesn't have a specific path in the snapshot. - delete sourceMapContentParsed.file - delete sourceMapContentParsed.sources - - if (process.env.IS_TURBOPACK_TEST) { - // Turbopack always uses lightningcss - expect(sourceMapContentParsed).toMatchInlineSnapshot(` + ) + + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Build failed') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + afterAll(async () => { + nextConfig.delete() + }) + + it(`should've compiled and prefixed`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheetUrl = cssSheet.attr('href') + + const cssContent = await fetchViaHTTP(appPort, stylesheetUrl).then( + (res) => res.text() + ) + + const cssContentWithoutSourceMap = cssContent + .replace(/\/\*.*?\*\/\n?/g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0px,0px)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` + ) + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0px,0px)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` + ) + } else if (useLightningcss) { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0,0)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` + ) + } else { + expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( + `"@media (min-width:480px) and (max-width:767px){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0,0)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:80%}"` + ) + } + + // Contains a source map + expect(cssContent).toMatch( + /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\// + ) + + const sourceMapUrl = /\/\*#\s*sourceMappingURL=(.+\.map)\s*\*\//.exec( + cssContent + )[1] + const actualSourceMapUrl = stylesheetUrl.replace( + /[^/]+$/, + sourceMapUrl + ) + + const sourceMapContent = await fetchViaHTTP( + appPort, + actualSourceMapUrl + ).then((res) => res.text()) + const sourceMapContentParsed = JSON.parse(sourceMapContent) + // Ensure it doesn't have a specific path in the snapshot. + delete sourceMapContentParsed.file + delete sourceMapContentParsed.sources + + if (process.env.IS_TURBOPACK_TEST) { + // Turbopack always uses lightningcss + expect(sourceMapContentParsed).toMatchInlineSnapshot(` { "mappings": "AAAA,qDACE,2BAKF,0DAIA,kDAIA,uCAIA", "names": [], @@ -149,8 +145,8 @@ module.exports = { "version": 3, } `) - } else if (useLightningcss) { - expect(sourceMapContentParsed).toMatchInlineSnapshot(` + } else if (useLightningcss) { + expect(sourceMapContentParsed).toMatchInlineSnapshot(` { "ignoreList": [], "mappings": "AAAA,qDACE,cACE,WACF,CACF,CAEA,cACE,2CACF,CAEA,mBACE,0BACF,CAEA,oBACE,kBACF,CAEA,mDACE,UACF", @@ -184,8 +180,8 @@ module.exports = { "version": 3, } `) - } else { - expect(sourceMapContentParsed).toMatchInlineSnapshot(` + } else { + expect(sourceMapContentParsed).toMatchInlineSnapshot(` { "ignoreList": [], "mappings": "AAAA,+CACE,cACE,WACF,CACF,CAEA,cACE,2CACF,CAEA,mBACE,0BACF,CAEA,oBACE,kBACF,CAEA,mDACE,WACF", @@ -218,25 +214,22 @@ module.exports = { "version": 3, } `) - } - }) } - ) + }) }) + }) - describe('React Lifecyce Order (production)', () => { - const appDir = join(fixturesDir, 'transition-react') - const nextConfig = new File(join(appDir, 'next.config.js')) - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) + describe('React Lifecyce Order (production)', () => { + const appDir = join(fixturesDir, 'transition-react') + const nextConfig = new File(join(appDir, 'next.config.js')) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) - describe.each([true, false])( - `useLightnincsss(%s)`, - (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -244,125 +237,49 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) - - let appPort - let app - beforeAll(async () => { - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it('should have the correct color on mount after navigation', async () => { - let browser - try { - browser = await webdriver(appPort, '/') - - // Navigate to other: - await browser.waitForElementByCss('#link-other').click() - const text = await browser - .waitForElementByCss('#red-title') - .text() - expect(text).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`) - } finally { - if (browser) { - await browser.close() - } - } - }) - } - ) - }) + ) + }) - describe('Has CSS in computed styles in Production', () => { - const appDir = join(fixturesDir, 'multi-page') - const nextConfig = new File(join(appDir, 'next.config.js')) + let appPort + let app + beforeAll(async () => { + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Build failed') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) - describe.each([true, false])( - `useLightnincsss(%s)`, - (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` -const config = require('../next.config.js'); -module.exports = { - ...config, - experimental: { - useLightningcss: ${useLightningcss} - } -}` - ) - }) - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it('should have CSS for page', async () => { - const browser = await webdriver(appPort, '/page2') - - const currentColor = await browser.eval( - `window.getComputedStyle(document.querySelector('.blue-text')).color` - ) - expect(currentColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`) - }) - - it(`should've preloaded the CSS file and injected it in `, async () => { - const content = await renderViaHTTP(appPort, '/page2') - const $ = cheerio.load(content) - - const cssPreload = $('link[rel="preload"][as="style"]') - expect(cssPreload.length).toBe(1) - expect(cssPreload.attr('href')).toMatch( - /^\/_next\/static\/.*\.css$/ - ) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - expect(cssSheet.attr('href')).toMatch( - /^\/_next\/static\/.*\.css$/ - ) - - /* ensure CSS preloaded first */ - const allPreloads = [].slice.call($('link[rel="preload"]')) - const styleIndexes = allPreloads.flatMap((p, i) => - p.attribs.as === 'style' ? i : [] - ) - expect(styleIndexes).toEqual([0]) - }) + it('should have the correct color on mount after navigation', async () => { + let browser + try { + browser = await webdriver(appPort, '/') + + // Navigate to other: + await browser.waitForElementByCss('#link-other').click() + const text = await browser.waitForElementByCss('#red-title').text() + expect(text).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`) + } finally { + if (browser) { + await browser.close() + } } - ) + }) }) + }) - describe('Good CSS Import from node_modules', () => { - const appDir = join(fixturesDir, 'npm-import') - const nextConfig = new File(join(appDir, 'next.config.js')) + describe('Has CSS in computed styles in Production', () => { + const appDir = join(fixturesDir, 'multi-page') + const nextConfig = new File(join(appDir, 'next.config.js')) - describe.each([true, false])( - `useLightnincsss(%s)`, - (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -370,59 +287,63 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheet = cssSheet.attr('href') - - const cssContent = ( - await fetchViaHTTP(appPort, stylesheet).then((res) => - res.text() - ) - ) - .replace(/\/\*.*?\*\/\n?/g, '') - .trim() - - expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()).toMatch( - /nprogress/ - ) - }) + ) + }) + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Build failed') } - ) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have CSS for page', async () => { + const browser = await webdriver(appPort, '/page2') + + const currentColor = await browser.eval( + `window.getComputedStyle(document.querySelector('.blue-text')).color` + ) + expect(currentColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`) + }) + + it(`should've preloaded the CSS file and injected it in `, async () => { + const content = await renderViaHTTP(appPort, '/page2') + const $ = cheerio.load(content) + + const cssPreload = $('link[rel="preload"][as="style"]') + expect(cssPreload.length).toBe(1) + expect(cssPreload.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + expect(cssSheet.attr('href')).toMatch(/^\/_next\/static\/.*\.css$/) + + /* ensure CSS preloaded first */ + const allPreloads = [].slice.call($('link[rel="preload"]')) + const styleIndexes = allPreloads.flatMap((p, i) => + p.attribs.as === 'style' ? i : [] + ) + expect(styleIndexes).toEqual([0]) + }) }) + }) - describe('Good Nested CSS Import from node_modules', () => { - const appDir = join(fixturesDir, 'npm-import-nested') - const nextConfig = new File(join(appDir, 'next.config.js')) + describe('Good CSS Import from node_modules', () => { + const appDir = join(fixturesDir, 'npm-import') + const nextConfig = new File(join(appDir, 'next.config.js')) - describe.each([true, false])( - `useLightnincsss(%s)`, - (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -430,76 +351,48 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) - - let appPort - let app - beforeAll(async () => { - await remove(join(appDir, '.next')) - const { code } = await nextBuild(appDir) - if (code !== 0) { - throw new Error('Build failed') - } - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) - - it(`should've emitted a single CSS file`, async () => { - const content = await renderViaHTTP(appPort, '/') - const $ = cheerio.load(content) - - const cssSheet = $('link[rel="stylesheet"]') - expect(cssSheet.length).toBe(1) - - const stylesheet = cssSheet.attr('href') - - const cssContent = ( - await fetchViaHTTP(appPort, stylesheet).then((res) => - res.text() - ) - ) - .replace(/\/\*.*?\*\/\n?/g, '') - .trim() - - if (process.env.IS_TURBOPACK_TEST && useLightningcss) { - expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()) - .toMatchInlineSnapshot(` - ".other{color:#00f} - .test{color:red}" - `) - } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { - expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()) - .toMatchInlineSnapshot(` - ".other{color:#00f} - .test{color:red}" - `) - } else if (useLightningcss) { - expect( - cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim() - ).toMatchInlineSnapshot(`".other{color:#00f}.test{color:red}"`) - } else { - expect( - cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim() - ).toMatchInlineSnapshot(`".other{color:blue}.test{color:red}"`) - } - }) + ) + }) + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Build failed') } - ) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) + + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheet = cssSheet.attr('href') + + const cssContent = ( + await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) + ) + .replace(/\/\*.*?\*\/\n?/g, '') + .trim() + + expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()).toMatch( + /nprogress/ + ) + }) }) - } - ) -}) + }) -// https://github.com/vercel/next.js/issues/15468 -describe('CSS Property Ordering', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'next-issue-15468') + describe('Good Nested CSS Import from node_modules', () => { + const appDir = join(fixturesDir, 'npm-import-nested') const nextConfig = new File(join(appDir, 'next.config.js')) describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { @@ -531,20 +424,96 @@ module.exports = { await killApp(app) }) - it('should have the border width (property ordering)', async () => { - const browser = await webdriver(appPort, '/') + it(`should've emitted a single CSS file`, async () => { + const content = await renderViaHTTP(appPort, '/') + const $ = cheerio.load(content) - const width1 = await browser.eval( - `window.getComputedStyle(document.querySelector('.test1')).borderWidth` - ) - expect(width1).toMatchInlineSnapshot(`"0px"`) + const cssSheet = $('link[rel="stylesheet"]') + expect(cssSheet.length).toBe(1) + + const stylesheet = cssSheet.attr('href') - const width2 = await browser.eval( - `window.getComputedStyle(document.querySelector('.test2')).borderWidth` + const cssContent = ( + await fetchViaHTTP(appPort, stylesheet).then((res) => res.text()) ) - expect(width2).toMatchInlineSnapshot(`"5px"`) + .replace(/\/\*.*?\*\/\n?/g, '') + .trim() + + if (process.env.IS_TURBOPACK_TEST && useLightningcss) { + expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()) + .toMatchInlineSnapshot(` + ".other{color:#00f} + .test{color:red}" + `) + } else if (process.env.IS_TURBOPACK_TEST && !useLightningcss) { + expect(cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim()) + .toMatchInlineSnapshot(` + ".other{color:#00f} + .test{color:red}" + `) + } else if (useLightningcss) { + expect( + cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim() + ).toMatchInlineSnapshot(`".other{color:#00f}.test{color:red}"`) + } else { + expect( + cssContent.replace(/\/\*.*?\*\/\n?/g, '').trim() + ).toMatchInlineSnapshot(`".other{color:blue}.test{color:red}"`) + } }) }) - } - ) + }) + }) +}) + +// https://github.com/vercel/next.js/issues/15468 +describe('CSS Property Ordering', () => { + describe('production mode', () => { + const appDir = join(fixturesDir, 'next-issue-15468') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` +const config = require('../next.config.js'); +module.exports = { + ...config, + experimental: { + useLightningcss: ${useLightningcss} + } +}` + ) + }) + + let appPort + let app + beforeAll(async () => { + await remove(join(appDir, '.next')) + const { code } = await nextBuild(appDir) + if (code !== 0) { + throw new Error('Build failed') + } + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) + + it('should have the border width (property ordering)', async () => { + const browser = await webdriver(appPort, '/') + + const width1 = await browser.eval( + `window.getComputedStyle(document.querySelector('.test1')).borderWidth` + ) + expect(width1).toMatchInlineSnapshot(`"0px"`) + + const width2 = await browser.eval( + `window.getComputedStyle(document.querySelector('.test2')).borderWidth` + ) + expect(width2).toMatchInlineSnapshot(`"5px"`) + }) + }) + }) }) diff --git a/test/integration/css/test/css-modules.test.js b/test/integration/css/test/css-modules.test.js index f1fde689df62f..129ba43d85baa 100644 --- a/test/integration/css/test/css-modules.test.js +++ b/test/integration/css/test/css-modules.test.js @@ -134,80 +134,74 @@ useLightningcss: ${useLightningcss} }) describe('should handle unresolved files gracefully', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const workDir = join(fixturesDir, 'unresolved-css-url') - - it('should build correctly', async () => { - await remove(join(workDir, '.next')) - const { code } = await nextBuild(workDir) - expect(code).toBe(0) - }) + describe('production mode', () => { + const workDir = join(fixturesDir, 'unresolved-css-url') - it('should have correct file references in CSS output', async () => { - const cssFolder = join(workDir, '.next', 'static') - const cssFiles = nodeFs - .readdirSync(cssFolder, { - recursive: true, - encoding: 'utf8', - }) - .filter((f) => f.endsWith('.css')) - // Ensure the loop is more deterministic - .sort() + it('should build correctly', async () => { + await remove(join(workDir, '.next')) + const { code } = await nextBuild(workDir) + expect(code).toBe(0) + }) - expect(cssFiles).not.toBeEmpty() + it('should have correct file references in CSS output', async () => { + const cssFolder = join(workDir, '.next', 'static') + const cssFiles = nodeFs + .readdirSync(cssFolder, { + recursive: true, + encoding: 'utf8', + }) + .filter((f) => f.endsWith('.css')) + // Ensure the loop is more deterministic + .sort() - for (const file of cssFiles) { - const content = await readFile(join(cssFolder, file), 'utf8') + expect(cssFiles).not.toBeEmpty() - const svgCount = content.match(/\(\/vercel\.svg/g).length - expect(svgCount === 1 || svgCount === 2).toBe(true) + for (const file of cssFiles) { + const content = await readFile(join(cssFolder, file), 'utf8') - if (process.env.IS_TURBOPACK_TEST) { - // With Turbopack these are combined and the path is relative. - const mediaCount = content.match(/\(\.\.\/media/g).length - expect(mediaCount === 1 || mediaCount === 2).toBe(true) - } else { - expect(content.match(/\(\/_next\/static\/media/g).length).toBe(1) - } - const httpsCount = content.match(/\(https:\/\//g).length - expect(httpsCount === 1 || httpsCount === 2).toBe(true) + const svgCount = content.match(/\(\/vercel\.svg/g).length + expect(svgCount === 1 || svgCount === 2).toBe(true) + + if (process.env.IS_TURBOPACK_TEST) { + // With Turbopack these are combined and the path is relative. + const mediaCount = content.match(/\(\.\.\/media/g).length + expect(mediaCount === 1 || mediaCount === 2).toBe(true) + } else { + expect(content.match(/\(\/_next\/static\/media/g).length).toBe(1) } - }) - } - ) + const httpsCount = content.match(/\(https:\/\//g).length + expect(httpsCount === 1 || httpsCount === 2).toBe(true) + } + }) + }) }) describe('Data URLs', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const workDir = join(fixturesDir, 'data-url') - - it('should compile successfully', async () => { - await remove(join(workDir, '.next')) - const { code } = await nextBuild(workDir) - expect(code).toBe(0) - }) + describe('production mode', () => { + const workDir = join(fixturesDir, 'data-url') - it('should have emitted expected files', async () => { - const cssFolder = join(workDir, '.next', 'static') - const cssFiles = nodeFs - .readdirSync(cssFolder, { - recursive: true, - encoding: 'utf8', - }) - .filter((f) => f.endsWith('.css')) + it('should compile successfully', async () => { + await remove(join(workDir, '.next')) + const { code } = await nextBuild(workDir) + expect(code).toBe(0) + }) - expect(cssFiles.length).toBe(1) - const cssContent = await readFile(join(cssFolder, cssFiles[0]), 'utf8') - expect(cssContent.replace(/\/\*.*?\*\/n/g, '').trim()).toMatch( - /background:url\("?data:[^"]+"?\)/ - ) - }) - } - ) + it('should have emitted expected files', async () => { + const cssFolder = join(workDir, '.next', 'static') + const cssFiles = nodeFs + .readdirSync(cssFolder, { + recursive: true, + encoding: 'utf8', + }) + .filter((f) => f.endsWith('.css')) + + expect(cssFiles.length).toBe(1) + const cssContent = await readFile(join(cssFolder, cssFiles[0]), 'utf8') + expect(cssContent.replace(/\/\*.*?\*\/n/g, '').trim()).toMatch( + /background:url\("?data:[^"]+"?\)/ + ) + }) + }) }) describe('Ordering with Global CSS and Modules (dev)', () => { @@ -310,16 +304,14 @@ useLightningcss: ${useLightningcss} }) describe('Ordering with Global CSS and Modules (prod)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - const appDir = join(fixturesDir, 'global-and-module-ordering') - const nextConfig = new File(join(appDir, 'next.config.js')) + describe('production mode', () => { + const appDir = join(fixturesDir, 'global-and-module-ordering') + const nextConfig = new File(join(appDir, 'next.config.js')) - describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -327,41 +319,40 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) + ) + }) - let appPort - let app - let stdout - let code - beforeAll(async () => { - await remove(join(appDir, '.next')) - ;({ code, stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) + let appPort + let app + let stdout + let code + beforeAll(async () => { + await remove(join(appDir, '.next')) + ;({ code, stdout } = await nextBuild(appDir, [], { + stdout: true, + })) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) - it('should have compiled successfully', () => { - expect(code).toBe(0) - expect(stdout).toMatch(/Compiled successfully/) - }) + it('should have compiled successfully', () => { + expect(code).toBe(0) + expect(stdout).toMatch(/Compiled successfully/) + }) - it('should have the correct color (css ordering)', async () => { - const browser = await webdriver(appPort, '/') + it('should have the correct color (css ordering)', async () => { + const browser = await webdriver(appPort, '/') - const currentColor = await browser.eval( - `window.getComputedStyle(document.querySelector('#blueText')).color` - ) - expect(currentColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`) - }) + const currentColor = await browser.eval( + `window.getComputedStyle(document.querySelector('#blueText')).color` + ) + expect(currentColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`) }) - } - ) + }) + }) }) // https://github.com/vercel/next.js/issues/12445 @@ -521,41 +512,35 @@ module.exports = { }) } - ;(process.env.TURBOPACK_BUILD ? describe.skip : describe)( - 'development mode', - () => { - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - beforeAll(async () => { - appPort = await findPort() - app = await launchApp(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) + describe('development mode', () => { + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) - tests(true) - } - ) - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - beforeAll(async () => { - await nextBuild(appDir, [], {}) - appPort = await findPort() - app = await nextStart(appDir, appPort) - }) - afterAll(async () => { - await killApp(app) - }) + tests(true) + }) + describe('production mode', () => { + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + beforeAll(async () => { + await nextBuild(appDir, [], {}) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await killApp(app) + }) - tests() - } - ) + tests() + }) }) } ) diff --git a/test/integration/css/test/css-rendering.test.js b/test/integration/css/test/css-rendering.test.js index b9b61aa033f22..91f3f44736ce2 100644 --- a/test/integration/css/test/css-rendering.test.js +++ b/test/integration/css/test/css-rendering.test.js @@ -15,19 +15,15 @@ import { join } from 'path' const fixturesDir = join(__dirname, '../..', 'css-fixtures') describe('CSS Support', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - describe('CSS Import from node_modules', () => { - const appDir = join(fixturesDir, 'npm-import-bad') - const nextConfig = new File(join(appDir, 'next.config.js')) - - describe.each([true, false])( - `useLightnincsss(%s)`, - (useLightningcss) => { - beforeAll(async () => { - nextConfig.write( - ` + describe('production mode', () => { + describe('CSS Import from node_modules', () => { + const appDir = join(fixturesDir, 'npm-import-bad') + const nextConfig = new File(join(appDir, 'next.config.js')) + + describe.each([true, false])(`useLightnincsss(%s)`, (useLightningcss) => { + beforeAll(async () => { + nextConfig.write( + ` const config = require('../next.config.js'); module.exports = { ...config, @@ -35,28 +31,24 @@ module.exports = { useLightningcss: ${useLightningcss} } }` - ) - }) - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) - - it('should fail the build', async () => { - const { code, stderr } = await nextBuild(appDir, [], { - stderr: true, - }) - - expect(code).toBe(0) - expect(stderr).not.toMatch( - /Can't resolve '[^']*?nprogress[^']*?'/ - ) - expect(stderr).not.toMatch(/Build error occurred/) - }) - } - ) + ) + }) + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + it('should fail the build', async () => { + const { code, stderr } = await nextBuild(appDir, [], { + stderr: true, + }) + + expect(code).toBe(0) + expect(stderr).not.toMatch(/Can't resolve '[^']*?nprogress[^']*?'/) + expect(stderr).not.toMatch(/Build error occurred/) + }) }) - } - ) + }) + }) // https://github.com/vercel/next.js/issues/18557 describe('CSS page transition inject