diff --git a/test/integration/url-imports/next.config.js b/test/e2e/url-imports/next.config.js similarity index 100% rename from test/integration/url-imports/next.config.js rename to test/e2e/url-imports/next.config.js diff --git a/test/integration/url-imports/source/value1.js b/test/e2e/url-imports/next.lock/data/http_localhost_12345/value1_d8c72f577995000e3fad.js similarity index 100% rename from test/integration/url-imports/source/value1.js rename to test/e2e/url-imports/next.lock/data/http_localhost_12345/value1_d8c72f577995000e3fad.js diff --git a/test/integration/url-imports/source/value2.js b/test/e2e/url-imports/next.lock/data/http_localhost_12345/value2_c78b9332f4998e489c87.js similarity index 100% rename from test/integration/url-imports/source/value2.js rename to test/e2e/url-imports/next.lock/data/http_localhost_12345/value2_c78b9332f4998e489c87.js diff --git a/test/integration/url-imports/source/value3.js b/test/e2e/url-imports/next.lock/data/http_localhost_12345/value3_206680f033f0d0f3b538.js similarity index 100% rename from test/integration/url-imports/source/value3.js rename to test/e2e/url-imports/next.lock/data/http_localhost_12345/value3_206680f033f0d0f3b538.js diff --git a/test/integration/url-imports/source/value4.js b/test/e2e/url-imports/next.lock/data/http_localhost_12345/value4_fcfa0c15487b3667cdfd.js similarity index 100% rename from test/integration/url-imports/source/value4.js rename to test/e2e/url-imports/next.lock/data/http_localhost_12345/value4_fcfa0c15487b3667cdfd.js diff --git a/test/e2e/url-imports/next.lock/lock.json b/test/e2e/url-imports/next.lock/lock.json new file mode 100644 index 00000000000000..0a99ed025efbc9 --- /dev/null +++ b/test/e2e/url-imports/next.lock/lock.json @@ -0,0 +1,24 @@ +{ + "http://localhost:12345/value1.js": { + "integrity": "sha512-S1eh3STyIGuRSfoAVU0jhxVY2MoRXSC/JduKMKuATb91ArhG0G2rvRNsGvD2kZo/jENlbrMtWNkzK2dGLgaUfg==", + "contentType": "application/javascript; charset=UTF-8" + }, + "http://localhost:12345/value2.js": { + "integrity": "sha512-R4XoB/ZTbRL9FGcM5d3hkxtxmMUXaKNKCqRKZPDy1v7Hh61HPLidPQHga1XMurakZPoJnCC5a5jRdOAagn3LRA==", + "contentType": "application/javascript; charset=UTF-8" + }, + "http://localhost:12345/value3.js": { + "integrity": "sha512-xtYaDPwejlXaMwQOdnYldln3wA5UYqIaJXMuCdBmyjgRX3zSKKd/AbGYobURfITmpzkz7U7E5GEK2Ju17qCZkw==", + "contentType": "application/javascript; charset=UTF-8" + }, + "http://localhost:12345/value4.js": { + "integrity": "sha512-orh6tVnh1jjxWNNLduiv0pUcW0guzwTmy52JQGdz4D2LL2IgIlJaC0w4+YBtIBXa2kKGho839WgGAK0sC0Folw==", + "contentType": "application/javascript; charset=UTF-8" + }, + "https://github.com/vercel/next.js/raw/canary/test/integration/url/public/vercel.png": "no-cache", + "https://github.com/vercel/next.js/raw/canary/test/integration/url/public/vercel.png?_=image": "no-cache", + "https://github.com/vercel/next.js/raw/canary/test/integration/url/public/vercel.png?_=ssg": "no-cache", + "https://github.com/vercel/next.js/raw/canary/test/integration/url/public/vercel.png?_=ssr": "no-cache", + "https://github.com/vercel/next.js/raw/canary/test/integration/url/public/vercel.png?_=static": "no-cache", + "version": 1 +} diff --git a/test/integration/url-imports/pages/api/value.js b/test/e2e/url-imports/pages/api/value.js similarity index 100% rename from test/integration/url-imports/pages/api/value.js rename to test/e2e/url-imports/pages/api/value.js diff --git a/test/integration/url-imports/pages/css.js b/test/e2e/url-imports/pages/css.js similarity index 100% rename from test/integration/url-imports/pages/css.js rename to test/e2e/url-imports/pages/css.js diff --git a/test/integration/url-imports/pages/css.module.css b/test/e2e/url-imports/pages/css.module.css similarity index 100% rename from test/integration/url-imports/pages/css.module.css rename to test/e2e/url-imports/pages/css.module.css diff --git a/test/integration/url-imports/pages/image.js b/test/e2e/url-imports/pages/image.js similarity index 100% rename from test/integration/url-imports/pages/image.js rename to test/e2e/url-imports/pages/image.js diff --git a/test/integration/url-imports/pages/ssg.js b/test/e2e/url-imports/pages/ssg.js similarity index 100% rename from test/integration/url-imports/pages/ssg.js rename to test/e2e/url-imports/pages/ssg.js diff --git a/test/integration/url-imports/pages/ssr.js b/test/e2e/url-imports/pages/ssr.js similarity index 100% rename from test/integration/url-imports/pages/ssr.js rename to test/e2e/url-imports/pages/ssr.js diff --git a/test/integration/url-imports/pages/static.js b/test/e2e/url-imports/pages/static.js similarity index 100% rename from test/integration/url-imports/pages/static.js rename to test/e2e/url-imports/pages/static.js diff --git a/test/integration/url-imports/public/vercel.png b/test/e2e/url-imports/public/vercel.png similarity index 100% rename from test/integration/url-imports/public/vercel.png rename to test/e2e/url-imports/public/vercel.png diff --git a/test/e2e/url-imports/source/value1.js b/test/e2e/url-imports/source/value1.js new file mode 100644 index 00000000000000..a9334acdeb9bce --- /dev/null +++ b/test/e2e/url-imports/source/value1.js @@ -0,0 +1 @@ +export default 42 // 1 diff --git a/test/e2e/url-imports/source/value2.js b/test/e2e/url-imports/source/value2.js new file mode 100644 index 00000000000000..806efcbdf1d494 --- /dev/null +++ b/test/e2e/url-imports/source/value2.js @@ -0,0 +1 @@ +export default 42 // 2 diff --git a/test/e2e/url-imports/source/value3.js b/test/e2e/url-imports/source/value3.js new file mode 100644 index 00000000000000..6ab694c37a388f --- /dev/null +++ b/test/e2e/url-imports/source/value3.js @@ -0,0 +1 @@ +export default 42 // 3 diff --git a/test/e2e/url-imports/source/value4.js b/test/e2e/url-imports/source/value4.js new file mode 100644 index 00000000000000..1295372d0b9f54 --- /dev/null +++ b/test/e2e/url-imports/source/value4.js @@ -0,0 +1 @@ +export default 42 // 4 diff --git a/test/e2e/url-imports/url-imports.test.ts b/test/e2e/url-imports/url-imports.test.ts new file mode 100644 index 00000000000000..4bf83fcf2df1e5 --- /dev/null +++ b/test/e2e/url-imports/url-imports.test.ts @@ -0,0 +1,94 @@ +import { + getBrowserBodyText, + startStaticServer, + stopApp, + retry, +} from 'next-test-utils' +import { FileRef, nextTestSetup, isNextDev } from 'e2e-utils' +import { join } from 'path' + +// experimental.urlImports is not implemented in Turbopack +;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( + `Handle url imports`, + () => { + let staticServer + let staticServerPort + beforeAll(async () => { + staticServerPort = 12345 + staticServer = await startStaticServer( + join(__dirname, 'source'), + undefined, + staticServerPort + ) + }) + afterAll(async () => { + await stopApp(staticServer) + }) + + const { next } = nextTestSetup({ + files: isNextDev + ? { + // exclude next.lock here, should be generated automatically in dev + 'next.config.js': new FileRef(join(__dirname, 'next.config.js')), + pages: new FileRef(join(__dirname, 'pages')), + public: new FileRef(join(__dirname, 'public')), + } + : __dirname, + }) + + const expectedServer = + /Hello 42\+42\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/ + const expectedClient = new RegExp( + expectedServer.source.replace(//g, '') + ) + + for (const page of ['/static', '/ssr', '/ssg']) { + it(`should render the ${page} page`, async () => { + const html = await next.render(page) + expect(html).toMatch(expectedServer) + }) + + it(`should client-render the ${page} page`, async () => { + const browser = await next.browser(page) + await retry(async () => + expect(await getBrowserBodyText(browser)).toMatch(expectedClient) + ) + }) + } + + it(`should render a static url image import`, async () => { + const browser = await next.browser('/image') + await browser.waitForElementByCss('#static-image') + await retry(async () => + expect( + await browser.elementByCss('#static-image').getAttribute('src') + ).toMatch( + /^\/_next\/image\?url=%2F_next%2Fstatic%2Fmedia%2Fvercel\.[0-9a-f]{8}\.png&/ + ) + ) + }) + + it(`should allow url import in css`, async () => { + const browser = await next.browser('/css') + + await browser.waitForElementByCss('#static-css') + await retry(async () => + expect( + await browser + .elementByCss('#static-css') + .getComputedCss('background-image') + ).toMatch( + /^url\("http:\/\/localhost:\d+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png"\)$/ + ) + ) + }) + + it('should respond on value api', async () => { + const data = await next + .fetch('/api/value') + .then((res) => res.ok && res.json()) + + expect(data).toEqual({ value: 42 }) + }) + } +) diff --git a/test/integration/url/pages/api/basename.js b/test/e2e/url/pages/api/basename.js similarity index 100% rename from test/integration/url/pages/api/basename.js rename to test/e2e/url/pages/api/basename.js diff --git a/test/integration/url/pages/api/size.js b/test/e2e/url/pages/api/size.js similarity index 100% rename from test/integration/url/pages/api/size.js rename to test/e2e/url/pages/api/size.js diff --git a/test/integration/url/pages/ssg.js b/test/e2e/url/pages/ssg.js similarity index 100% rename from test/integration/url/pages/ssg.js rename to test/e2e/url/pages/ssg.js diff --git a/test/integration/url/pages/ssr.js b/test/e2e/url/pages/ssr.js similarity index 100% rename from test/integration/url/pages/ssr.js rename to test/e2e/url/pages/ssr.js diff --git a/test/integration/url/pages/static.js b/test/e2e/url/pages/static.js similarity index 100% rename from test/integration/url/pages/static.js rename to test/e2e/url/pages/static.js diff --git a/test/integration/url/public/vercel.png b/test/e2e/url/public/vercel.png similarity index 100% rename from test/integration/url/public/vercel.png rename to test/e2e/url/public/vercel.png diff --git a/test/e2e/url/url.test.ts b/test/e2e/url/url.test.ts new file mode 100644 index 00000000000000..7a11eff4aaa658 --- /dev/null +++ b/test/e2e/url/url.test.ts @@ -0,0 +1,46 @@ +import { getBrowserBodyText, retry } from 'next-test-utils' +import { nextTestSetup } from 'e2e-utils' + +describe(`Handle new URL asset references`, () => { + const { next } = nextTestSetup({ + files: __dirname, + }) + + const expectedServer = + /Hello \/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/ + const expectedClient = new RegExp( + expectedServer.source.replace(//g, '') + ) + + for (const page of ['/static', '/ssr', '/ssg']) { + it(`should render the ${page} page`, async () => { + const html = await next.render(page) + expect(html).toMatch(expectedServer) + }) + + it(`should client-render the ${page} page`, async () => { + const browser = await next.browser(page) + await retry(async () => + expect(await getBrowserBodyText(browser)).toMatch(expectedClient) + ) + }) + } + + it('should respond on size api', async () => { + const data = await next + .fetch('/api/size') + .then((res) => res.ok && res.json()) + + expect(data).toEqual({ size: 30079 }) + }) + + it('should respond on basename api', async () => { + const data = await next + .fetch('/api/basename') + .then((res) => res.ok && res.json()) + + expect(data).toEqual({ + basename: expect.stringMatching(/^vercel\.[0-9a-f]{8}\.png$/), + }) + }) +}) diff --git a/test/integration/url-imports/.gitignore b/test/integration/url-imports/.gitignore deleted file mode 100644 index 3d389aacfc333b..00000000000000 --- a/test/integration/url-imports/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# this is only needed for the test case -# Do not ignore that in real apps -next.lock \ No newline at end of file diff --git a/test/integration/url-imports/test/index.test.js b/test/integration/url-imports/test/index.test.js deleted file mode 100644 index c8015dd8a73252..00000000000000 --- a/test/integration/url-imports/test/index.test.js +++ /dev/null @@ -1,125 +0,0 @@ -/* eslint-disable no-loop-func */ -/* eslint-env jest */ - -import fs from 'fs-extra' -import { join } from 'path' -import { - nextBuild, - findPort, - nextStart, - killApp, - renderViaHTTP, - fetchViaHTTP, - launchApp, - getBrowserBodyText, - check, - startStaticServer, - stopApp, -} from 'next-test-utils' -import webdriver from 'next-webdriver' - -jest.setTimeout(1000 * 60 * 2) -const appDir = join(__dirname, '../') - -// experimental.urlImports is not implemented in Turbopack -;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)( - `Handle url imports`, - () => { - let staticServer - let staticServerPort - beforeAll(async () => { - await fs.remove(join(appDir, 'next.lock')) - staticServerPort = 12345 - staticServer = await startStaticServer( - join(appDir, 'source'), - undefined, - staticServerPort - ) - }) - afterAll(async () => { - await stopApp(staticServer) - }) - - for (const dev of [true, false]) { - describe(dev ? 'with next dev' : 'with next build', () => { - let appPort - let app - beforeAll(async () => { - await fs.remove(join(appDir, '.next')) - if (dev) { - appPort = await findPort() - app = await launchApp(appDir, appPort) - } else { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - } - }) - afterAll(async () => { - await killApp(app) - }) - const expectedServer = - /Hello 42\+42\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/ - const expectedClient = new RegExp( - expectedServer.source.replace(//g, '') - ) - - for (const page of ['/static', '/ssr', '/ssg']) { - it(`should render the ${page} page`, async () => { - const html = await renderViaHTTP(appPort, page) - expect(html).toMatch(expectedServer) - }) - - it(`should client-render the ${page} page`, async () => { - let browser - try { - browser = await webdriver(appPort, page) - await check(() => getBrowserBodyText(browser), expectedClient) - } finally { - await browser.close() - } - }) - } - - it(`should render a static url image import`, async () => { - let browser - try { - browser = await webdriver(appPort, '/image') - await browser.waitForElementByCss('#static-image') - await check( - () => browser.elementByCss('#static-image').getAttribute('src'), - /^\/_next\/image\?url=%2F_next%2Fstatic%2Fmedia%2Fvercel\.[0-9a-f]{8}\.png&/ - ) - } finally { - await browser.close() - } - }) - - it(`should allow url import in css`, async () => { - let browser - try { - browser = await webdriver(appPort, '/css') - await browser.waitForElementByCss('#static-css') - await check( - () => - browser - .elementByCss('#static-css') - .getComputedCss('background-image'), - /^url\("http:\/\/localhost:\d+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png"\)$/ - ) - } finally { - await browser.close() - } - }) - - it('should respond on value api', async () => { - const data = await fetchViaHTTP(appPort, '/api/value').then( - (res) => res.ok && res.json() - ) - - expect(data).toEqual({ value: 42 }) - }) - }) - } - } -) diff --git a/test/integration/url/test/index.test.js b/test/integration/url/test/index.test.js deleted file mode 100644 index ad860c21ae195b..00000000000000 --- a/test/integration/url/test/index.test.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable no-loop-func */ -/* eslint-env jest */ - -import fs from 'fs-extra' -import { join } from 'path' -import { - nextBuild, - findPort, - nextStart, - killApp, - renderViaHTTP, - fetchViaHTTP, - launchApp, - getBrowserBodyText, - check, -} from 'next-test-utils' -import webdriver from 'next-webdriver' - -jest.setTimeout(1000 * 60 * 2) -const appDir = join(__dirname, '../') - -for (const dev of [false, true]) { - ;(process.env.IS_TURBOPACK_TEST && !dev ? describe.skip : describe)( - `Handle new URL asset references in next ${dev ? 'dev' : 'build'}`, - () => { - let appPort - let app - beforeAll(async () => { - await fs.remove(join(appDir, '.next')) - if (dev) { - appPort = await findPort() - app = await launchApp(appDir, appPort) - } else { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - } - }) - afterAll(() => killApp(app)) - - const expectedServer = - /Hello \/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/ - const expectedClient = new RegExp( - expectedServer.source.replace(//g, '') - ) - - for (const page of ['/static', '/ssr', '/ssg']) { - it(`should render the ${page} page`, async () => { - const html = await renderViaHTTP(appPort, page) - expect(html).toMatch(expectedServer) - }) - - it(`should client-render the ${page} page`, async () => { - let browser - try { - browser = await webdriver(appPort, page) - await check(() => getBrowserBodyText(browser), expectedClient) - } finally { - await browser.close() - } - }) - } - - it('should respond on size api', async () => { - const data = await fetchViaHTTP(appPort, '/api/size').then( - (res) => res.ok && res.json() - ) - - expect(data).toEqual({ size: 30079 }) - }) - - it('should respond on basename api', async () => { - const data = await fetchViaHTTP(appPort, '/api/basename').then( - (res) => res.ok && res.json() - ) - - expect(data).toEqual({ - basename: expect.stringMatching(/^vercel\.[0-9a-f]{8}\.png$/), - }) - }) - } - ) -}