From 94e54754a8e4ac25b54896eccd7f9773729ee806 Mon Sep 17 00:00:00 2001 From: Nicholas Cunningham Date: Mon, 2 Jun 2025 10:52:35 -0600 Subject: [PATCH] fix(js): enable end-to-end tests for Vue application in dev mode (#31415) This PR updates Vite's E2E testing setup for the Vue plugin. Instead of commenting out the serve for vite and rsbuild when using playwright we update the test to ensure the ports are available before attempting to run their preview target. --- e2e/vue/src/vue.test.ts | 89 ++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/e2e/vue/src/vue.test.ts b/e2e/vue/src/vue.test.ts index 8205c04ad9..4dc8d9fa82 100644 --- a/e2e/vue/src/vue.test.ts +++ b/e2e/vue/src/vue.test.ts @@ -5,6 +5,7 @@ import { runCLI, runE2ETests, uniq, + updateFile, } from '@nx/e2e/utils'; describe('Vue Plugin', () => { @@ -18,7 +19,7 @@ describe('Vue Plugin', () => { afterAll(() => cleanupProject()); - it('should serve application in dev mode', async () => { + it('should serve application in dev mode vite config', async () => { const app = uniq('app'); runCLI( @@ -32,12 +33,32 @@ describe('Vue Plugin', () => { `Successfully ran target build for project ${app}` ); - // TODO: enable this when tests are passing again. - // if (runE2ETests()) { - // const e2eResults = runCLI(`e2e ${app}-e2e --no-watch`); - // expect(e2eResults).toContain('Successfully ran target e2e'); - // expect(await killPorts()).toBeTruthy(); - // } + if (runE2ETests('playwright')) { + const availablePort = await getAvailablePort(); + + updateFile(`${app}-e2e/playwright.config.ts`, (content) => { + return content + .replace( + /const baseURL = process\.env\['BASE_URL'\] \|\| '[^']*';/, + `const baseURL = process.env['BASE_URL'] || 'http://localhost:${availablePort}';` + ) + .replace(/url: '[^']*'/, `url: 'http://localhost:${availablePort}'`); + }); + + updateFile(`${app}/vite.config.ts`, (content) => { + return content.replace( + /preview:\s*{[^}]*}/, + `preview: { + port: ${availablePort}, + host: 'localhost', + }` + ); + }); + + const e2eResults = runCLI(`e2e ${app}-e2e`); + expect(e2eResults).toContain('Successfully ran target e2e'); + expect(await killPorts(availablePort)).toBeTruthy(); + } }, 200_000); it('should serve application in dev mode with rsbuild', async () => { @@ -54,13 +75,31 @@ describe('Vue Plugin', () => { `Successfully ran target build for project ${app}` ); - // TODO: enable this when tests are passing again. - // Colum confirmed locally that the generated config and the playwright tests are working. - // if (runE2ETests()) { - // const e2eResults = runCLI(`e2e ${app}-e2e --no-watch`); - // expect(e2eResults).toContain('Successfully ran target e2e'); - // expect(await killPorts()).toBeTruthy(); - // } + if (runE2ETests('playwright')) { + const availablePort = await getAvailablePort(); + + updateFile(`${app}-e2e/playwright.config.ts`, (content) => { + return content + .replace( + /const baseURL = process\.env\['BASE_URL'\] \|\| '[^']*';/, + `const baseURL = process.env['BASE_URL'] || 'http://localhost:${availablePort}';` + ) + .replace(/url: '[^']*'/, `url: 'http://localhost:${availablePort}'`); + }); + + updateFile(`${app}/rsbuild.config.ts`, (content) => { + return content.replace( + /server:\s*{[^}]*}/, + `server: { + port: ${availablePort}, + }` + ); + }); + + const e2eResults = runCLI(`e2e ${app}-e2e`); + expect(e2eResults).toContain('Successfully ran target e2e'); + expect(await killPorts(availablePort)).toBeTruthy(); + } }, 200_000); it('should build library', async () => { @@ -76,3 +115,25 @@ describe('Vue Plugin', () => { ); }); }); + +async function getAvailablePort(): Promise { + const net = require('net'); + + return new Promise((resolve, reject) => { + const server = net.createServer(); + server.unref(); + server.on('error', reject); + + server.listen(0, () => { + const addressInfo = server.address(); + if (!addressInfo) { + reject(new Error('Failed to get server address')); + return; + } + const port = addressInfo.port; + server.close(() => { + resolve(port); + }); + }); + }); +}