From 6da78b2274c4b6ff178cbd98717e5b96999bf688 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Tue, 28 Jan 2025 14:28:25 -0500 Subject: [PATCH 01/11] test: use branch/alias deploys for e2e test suite to allow automatic cleanup --- tests/utils/create-e2e-fixture.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index 31cf3496e1..332fde7297 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -268,7 +268,7 @@ async function deploySite( console.log(`🚀 Building and deploying site...`) const outputFile = 'deploy-output.txt' - let cmd = `npx netlify deploy --build --site ${siteId}` + let cmd = `npx netlify deploy --build --site ${siteId} --alias next-e2e-tests` if (packagePath) { cmd += ` --filter ${packagePath}` @@ -278,11 +278,19 @@ async function deploySite( await execaCommand(cmd, { cwd: siteDir, all: true }).pipeAll?.(join(siteDir, outputFile)) const output = await readFile(join(siteDir, outputFile), 'utf-8') - const [url] = new RegExp(/https:.+\.netlify\.app/gm).exec(output) || [] + const [url] = + new RegExp( + /https:\/\/app\.netlify\.com\/sites\/next-runtime-testing\/deploys\/^[0-9a-f]+/gm, + ).exec(output) || [] if (!url) { throw new Error('Could not extract the URL from the build logs') } - const [deployID] = new URL(url).host.split('--') + + const deployID = url.split('/').pop() + if (!deployID) { + throw new Error('Could not extract DeployID from the build logs') + } + return { url, deployID, logs: output } } From 4dd8a7716734ee8dd60ad0a449f9cc91fa22609f Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 29 Jan 2025 10:42:56 -0500 Subject: [PATCH 02/11] chore: deletion is now automated by the system --- tools/e2e/cleanup-deploys.ts | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 tools/e2e/cleanup-deploys.ts diff --git a/tools/e2e/cleanup-deploys.ts b/tools/e2e/cleanup-deploys.ts deleted file mode 100644 index 67f3a3f3ad..0000000000 --- a/tools/e2e/cleanup-deploys.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { exec } from 'node:child_process' -import { SITE_ID, deleteDeploy } from '../../tests/utils/create-e2e-fixture.js' - -const runCommand = (cmd: string) => - new Promise((resolve, reject) => - exec(cmd, (err, stdout) => (err ? reject(err) : resolve(stdout))), - ) - -const output = await runCommand(`npx netlify api listSiteDeploys --data='{"site_id":"${SITE_ID}"}'`) -const deploys = JSON.parse(output) - -await Promise.allSettled(deploys.map((deploy) => deleteDeploy(deploy.id))) From ca7a82f38a9da78543ebb90e629ef86888200060 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 29 Jan 2025 11:27:44 -0500 Subject: [PATCH 03/11] chore: use constant for deploy alias --- tests/utils/create-e2e-fixture.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index 332fde7297..aa3888dee1 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -15,6 +15,7 @@ import { setNextVersionInFixture } from './next-version-helpers.mjs' const DEFAULT_SITE_ID = 'ee859ce9-44a7-46be-830b-ead85e445e53' export const SITE_ID = process.env.NETLIFY_SITE_ID ?? DEFAULT_SITE_ID const NEXT_VERSION = process.env.NEXT_VERSION || 'latest' +const NETLIFY_DEPLOY_ALIAS = 'next-e2e-tests' export interface DeployResult { deployID: string @@ -268,7 +269,7 @@ async function deploySite( console.log(`🚀 Building and deploying site...`) const outputFile = 'deploy-output.txt' - let cmd = `npx netlify deploy --build --site ${siteId} --alias next-e2e-tests` + let cmd = `npx netlify deploy --build --site ${siteId} --alias ${NETLIFY_DEPLOY_ALIAS}` if (packagePath) { cmd += ` --filter ${packagePath}` From ce599668727f8efab07936878edde4f8222e0280 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 29 Jan 2025 11:29:24 -0500 Subject: [PATCH 04/11] test: fix deploy url regex --- tests/utils/create-e2e-fixture.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index aa3888dee1..a62b490663 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -279,10 +279,7 @@ async function deploySite( await execaCommand(cmd, { cwd: siteDir, all: true }).pipeAll?.(join(siteDir, outputFile)) const output = await readFile(join(siteDir, outputFile), 'utf-8') - const [url] = - new RegExp( - /https:\/\/app\.netlify\.com\/sites\/next-runtime-testing\/deploys\/^[0-9a-f]+/gm, - ).exec(output) || [] + const [url] = new RegExp(/next-runtime-testing\/deploys\/[0-9a-f]+/gm).exec(output) || [] if (!url) { throw new Error('Could not extract the URL from the build logs') } From aba1db7251c93d5ed067e2facf038234ef83564c Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 29 Jan 2025 11:30:49 -0500 Subject: [PATCH 05/11] test: use deploy preview for test url --- tests/utils/create-e2e-fixture.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index a62b490663..3fbca01888 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -289,7 +289,11 @@ async function deploySite( throw new Error('Could not extract DeployID from the build logs') } - return { url, deployID, logs: output } + return { + url: `https://${deployID}--next-runtime-testing.netlify.app/`, + deployID, + logs: output, + } } export async function deleteDeploy(deployID?: string): Promise { From 81042da363eb2fdbae45eb4233b537b55450ee28 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 29 Jan 2025 13:00:16 -0500 Subject: [PATCH 06/11] chore: leverage regex named capture groups for deploy id and site name --- tests/utils/create-e2e-fixture.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index 3fbca01888..250c69134d 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -279,18 +279,16 @@ async function deploySite( await execaCommand(cmd, { cwd: siteDir, all: true }).pipeAll?.(join(siteDir, outputFile)) const output = await readFile(join(siteDir, outputFile), 'utf-8') - const [url] = new RegExp(/next-runtime-testing\/deploys\/[0-9a-f]+/gm).exec(output) || [] - if (!url) { - throw new Error('Could not extract the URL from the build logs') - } + const { siteName, deployID } = new RegExp( + /app\.netlify\.com\/sites\/(?.+)\/deploys\/(?[0-9a-f]+)/gm + ).exec(output)?.groups || {} - const deployID = url.split('/').pop() if (!deployID) { throw new Error('Could not extract DeployID from the build logs') } return { - url: `https://${deployID}--next-runtime-testing.netlify.app/`, + url: `https://${deployID}--${siteName}.netlify.app/`, deployID, logs: output, } From f0e2da0044a64f11de4129de55ad66f85a398d4a Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 29 Jan 2025 13:18:50 -0500 Subject: [PATCH 07/11] test: use branch/alias deploys for vercel tests --- tests/netlify-deploy.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/netlify-deploy.ts b/tests/netlify-deploy.ts index 25835dfd0e..482bbdbea0 100644 --- a/tests/netlify-deploy.ts +++ b/tests/netlify-deploy.ts @@ -129,10 +129,11 @@ export class NextDeployInstance extends NextInstance { const deployTitle = process.env.GITHUB_SHA ? `${testName} - ${process.env.GITHUB_SHA}` : testName + const deployAlias = 'vercel-next-e2e' const deployRes = await execa( 'npx', - ['netlify', 'deploy', '--build', '--message', deployTitle ?? ''], + ['netlify', 'deploy', '--build', '--message', deployTitle ?? '', '--alias', deployAlias], { cwd: this.testDir, reject: false, @@ -146,22 +147,23 @@ export class NextDeployInstance extends NextInstance { } try { - const [url] = new RegExp(/https:.+\.netlify\.app/gm).exec(deployRes.stdout) || [] - if (!url) { - throw new Error('Could not extract the URL from the build logs') + const deployUrlRegex = new RegExp( + /https:\/\/app\.netlify\.com\/sites\/(?.+)\/deploys\/(?[0-9a-f]+)/gm, + ).exec(deployRes.stdout) + const [buildLogsUrl] = deployUrlRegex || [] + const { deployID, siteName } = deployUrlRegex?.groups || {} + + if (!deployID) { + throw new Error('Could not extract DeployID from the build logs') } - const [deployID] = new URL(url).host.split('--') - this._url = url + + this._url = `https://${deployID}--${siteName}.netlify.app/` this._parsedUrl = new URL(this._url) this._deployId = deployID this._shouldDeleteDeploy = !process.env.NEXT_TEST_SKIP_CLEANUP this._cliOutput = deployRes.stdout + deployRes.stderr - require('console').log(`Deployment URL: ${this._url}`) - const [buildLogsUrl] = - new RegExp(/https:\/\/app\.netlify\.com\/sites\/.+\/deploys\/[0-9a-f]+/gm).exec( - deployRes.stdout, - ) || [] + require('console').log(`Deployment URL: ${this._url}`) if (buildLogsUrl) { require('console').log(`Logs: ${buildLogsUrl}`) } From 2662fea23fe1d5790ac19369e5c878936df0f63b Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Thu, 30 Jan 2025 10:36:38 -0500 Subject: [PATCH 08/11] chore: remove unused import --- tests/e2e/export.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/export.test.ts b/tests/e2e/export.test.ts index 916f668f97..ec930d0ff8 100644 --- a/tests/e2e/export.test.ts +++ b/tests/e2e/export.test.ts @@ -1,5 +1,4 @@ import { expect, type Locator } from '@playwright/test' -import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' import { test } from '../utils/playwright-helpers.js' const expectImageWasLoaded = async (locator: Locator) => { From b5f4be552d61776eaad2eb82ce04327a56cf5cab Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Thu, 30 Jan 2025 10:37:02 -0500 Subject: [PATCH 09/11] test: remove trailing slashes from deploy urls --- tests/netlify-deploy.ts | 2 +- tests/utils/create-e2e-fixture.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/netlify-deploy.ts b/tests/netlify-deploy.ts index 482bbdbea0..d7e4b76c88 100644 --- a/tests/netlify-deploy.ts +++ b/tests/netlify-deploy.ts @@ -157,7 +157,7 @@ export class NextDeployInstance extends NextInstance { throw new Error('Could not extract DeployID from the build logs') } - this._url = `https://${deployID}--${siteName}.netlify.app/` + this._url = `https://${deployID}--${siteName}.netlify.app` this._parsedUrl = new URL(this._url) this._deployId = deployID this._shouldDeleteDeploy = !process.env.NEXT_TEST_SKIP_CLEANUP diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index 250c69134d..fa6fc59e0f 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -288,7 +288,7 @@ async function deploySite( } return { - url: `https://${deployID}--${siteName}.netlify.app/`, + url: `https://${deployID}--${siteName}.netlify.app`, deployID, logs: output, } From 4dae38d06a2c0b0eb8618d3c26422970ba228246 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Thu, 30 Jan 2025 10:47:37 -0500 Subject: [PATCH 10/11] chore: format with prettier --- tests/utils/create-e2e-fixture.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index fa6fc59e0f..cc9c588496 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -279,9 +279,10 @@ async function deploySite( await execaCommand(cmd, { cwd: siteDir, all: true }).pipeAll?.(join(siteDir, outputFile)) const output = await readFile(join(siteDir, outputFile), 'utf-8') - const { siteName, deployID } = new RegExp( - /app\.netlify\.com\/sites\/(?.+)\/deploys\/(?[0-9a-f]+)/gm - ).exec(output)?.groups || {} + const { siteName, deployID } = + new RegExp(/app\.netlify\.com\/sites\/(?.+)\/deploys\/(?[0-9a-f]+)/gm).exec( + output, + )?.groups || {} if (!deployID) { throw new Error('Could not extract DeployID from the build logs') From 964ea6bdb930ae7eed1a8278839acc7a0202252e Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Thu, 30 Jan 2025 18:44:20 +0100 Subject: [PATCH 11/11] test: skip og image integration test in windows --- tests/integration/wasm.test.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/integration/wasm.test.ts b/tests/integration/wasm.test.ts index 679117de61..2de9050400 100644 --- a/tests/integration/wasm.test.ts +++ b/tests/integration/wasm.test.ts @@ -1,4 +1,5 @@ import { getLogger } from 'lambda-local' +import { platform } from 'node:process' import { v4 } from 'uuid' import { beforeEach, describe, expect, test, vi } from 'vitest' import { type FixtureTestContext } from '../utils/contexts.js' @@ -52,11 +53,16 @@ describe.each([ expect(og.headers['content-type']).toBe('image/png') }) - test('should work in app route with node runtime', async (ctx) => { - const ogNode = await invokeFunction(ctx, { url: '/og-node' }) - expect(ogNode.statusCode).toBe(200) - expect(ogNode.headers['content-type']).toBe('image/png') - }) + // on Node 18.20.6 on Windows, there seems to be an issue with OG image generation in this scenario + // that is reproducible with `next start` even outside of Netlify context + test.skipIf(platform === 'win32')( + 'should work in app route with node runtime', + async (ctx) => { + const ogNode = await invokeFunction(ctx, { url: '/og-node' }) + expect(ogNode.statusCode).toBe(200) + expect(ogNode.headers['content-type']).toBe('image/png') + }, + ) test('should work in middleware', async (ctx) => { const origin = new LocalServer()