From ffe0478fcc590fc58fcd28c5d2264f59843fa367 Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Wed, 18 Dec 2024 12:40:08 -0500 Subject: [PATCH 01/10] chore: create monorepo e2e spec --- e2e/fixtures/monorepo/package.json | 7 ++ .../monorepo/packages/waku-project/.gitignore | 7 ++ .../packages/waku-project/package.json | 23 +++++ .../packages/waku-project/postcss.config.js | 7 ++ .../waku-project/public/images/favicon.png | Bin 0 -> 5713 bytes .../waku-project/src/components/counter.tsx | 21 +++++ .../waku-project/src/components/footer.tsx | 18 ++++ .../waku-project/src/components/header.tsx | 11 +++ .../waku-project/src/pages/_layout.tsx | 39 +++++++++ .../packages/waku-project/src/pages/about.tsx | 32 +++++++ .../packages/waku-project/src/pages/index.tsx | 35 ++++++++ .../packages/waku-project/src/styles.css | 4 + .../packages/waku-project/tailwind.config.js | 4 + .../packages/waku-project/tsconfig.json | 15 ++++ e2e/monorepo.spec.ts | 81 ++++++++++++++++++ 15 files changed, 304 insertions(+) create mode 100644 e2e/fixtures/monorepo/package.json create mode 100644 e2e/fixtures/monorepo/packages/waku-project/.gitignore create mode 100644 e2e/fixtures/monorepo/packages/waku-project/package.json create mode 100644 e2e/fixtures/monorepo/packages/waku-project/postcss.config.js create mode 100644 e2e/fixtures/monorepo/packages/waku-project/public/images/favicon.png create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/components/footer.tsx create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/components/header.tsx create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/pages/_layout.tsx create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/pages/about.tsx create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx create mode 100644 e2e/fixtures/monorepo/packages/waku-project/src/styles.css create mode 100644 e2e/fixtures/monorepo/packages/waku-project/tailwind.config.js create mode 100644 e2e/fixtures/monorepo/packages/waku-project/tsconfig.json create mode 100644 e2e/monorepo.spec.ts diff --git a/e2e/fixtures/monorepo/package.json b/e2e/fixtures/monorepo/package.json new file mode 100644 index 000000000..1950a019e --- /dev/null +++ b/e2e/fixtures/monorepo/package.json @@ -0,0 +1,7 @@ +{ + "name": "monorepo", + "private": true, + "workspaces": [ + "packages/*" + ] +} diff --git a/e2e/fixtures/monorepo/packages/waku-project/.gitignore b/e2e/fixtures/monorepo/packages/waku-project/.gitignore new file mode 100644 index 000000000..ad583432d --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/.gitignore @@ -0,0 +1,7 @@ +node_modules +dist +.env* +*.tsbuildinfo +.cache +.DS_Store +*.pem diff --git a/e2e/fixtures/monorepo/packages/waku-project/package.json b/e2e/fixtures/monorepo/packages/waku-project/package.json new file mode 100644 index 000000000..644c9aa5b --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/package.json @@ -0,0 +1,23 @@ +{ + "name": "waku-project", + "version": "0.0.0", + "type": "module", + "private": true, + "scripts": { + "dev": "waku dev", + "build": "waku build", + "start": "waku start" + }, + "dependencies": { + "react": "19.0.0", + "react-dom": "19.0.0", + "react-server-dom-webpack": "19.0.0" + }, + "devDependencies": { + "@types/react": "19.0.1", + "@types/react-dom": "19.0.2", + "autoprefixer": "10.4.20", + "tailwindcss": "3.4.16", + "typescript": "5.7.2" + } +} diff --git a/e2e/fixtures/monorepo/packages/waku-project/postcss.config.js b/e2e/fixtures/monorepo/packages/waku-project/postcss.config.js new file mode 100644 index 000000000..709af5d83 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/postcss.config.js @@ -0,0 +1,7 @@ +/** @type {import('postcss-load-config').Config} */ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/public/images/favicon.png b/e2e/fixtures/monorepo/packages/waku-project/public/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd90d79081c0c40519bb3c583f5b43357b3fcd3b GIT binary patch literal 5713 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 DW2Q3= literal 0 HcmV?d00001 diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx new file mode 100644 index 000000000..c5b5e13a3 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx @@ -0,0 +1,21 @@ +'use client'; + +import { useState } from 'react'; + +export const Counter = () => { + const [count, setCount] = useState(0); + + const handleIncrement = () => setCount((c) => c + 1); + + return ( +
+
Count: {count}
+ +
+ ); +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/components/footer.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/components/footer.tsx new file mode 100644 index 000000000..8cfd9c897 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/components/footer.tsx @@ -0,0 +1,18 @@ +export const Footer = () => { + return ( + + ); +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/components/header.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/components/header.tsx new file mode 100644 index 000000000..1b03ba54d --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/components/header.tsx @@ -0,0 +1,11 @@ +import { Link } from 'waku'; + +export const Header = () => { + return ( +
+

+ Waku starter +

+
+ ); +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/pages/_layout.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/pages/_layout.tsx new file mode 100644 index 000000000..6d227c9f6 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/pages/_layout.tsx @@ -0,0 +1,39 @@ +import '../styles.css'; + +import type { ReactNode } from 'react'; + +import { Header } from '../components/header'; +import { Footer } from '../components/footer'; + +type RootLayoutProps = { children: ReactNode }; + +export default async function RootLayout({ children }: RootLayoutProps) { + const data = await getData(); + + return ( +
+ + +
+
+ {children} +
+
+
+ ); +} + +const getData = async () => { + const data = { + description: 'An internet website!', + icon: '/images/favicon.png', + }; + + return data; +}; + +export const getConfig = async () => { + return { + render: 'static', + } as const; +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/pages/about.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/pages/about.tsx new file mode 100644 index 000000000..15d4c90e1 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/pages/about.tsx @@ -0,0 +1,32 @@ +import { Link } from 'waku'; + +export default async function AboutPage() { + const data = await getData(); + + return ( +
+ {data.title} +

{data.headline}

+

{data.body}

+ + Return home + +
+ ); +} + +const getData = async () => { + const data = { + title: 'About', + headline: 'About Waku', + body: 'The minimal React framework', + }; + + return data; +}; + +export const getConfig = async () => { + return { + render: 'static', + } as const; +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx new file mode 100644 index 000000000..637efc9c8 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx @@ -0,0 +1,35 @@ +import { Link } from 'waku'; + +import { Counter } from '../components/counter'; + +export default async function HomePage() { + const data = await getData(); + + return ( +
+ {data.title} +

{data.headline}

+

{data.body}

+ + + About page + +
+ ); +} + +const getData = async () => { + const data = { + title: 'Waku', + headline: 'Waku', + body: 'Hello world!', + }; + + return data; +}; + +export const getConfig = async () => { + return { + render: 'static', + } as const; +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/styles.css b/e2e/fixtures/monorepo/packages/waku-project/src/styles.css new file mode 100644 index 000000000..4cb5445ab --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/src/styles.css @@ -0,0 +1,4 @@ +@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,700;1,400;1,700&display=swap'); +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/e2e/fixtures/monorepo/packages/waku-project/tailwind.config.js b/e2e/fixtures/monorepo/packages/waku-project/tailwind.config.js new file mode 100644 index 000000000..df5c92956 --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/tailwind.config.js @@ -0,0 +1,4 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{js,jsx,ts,tsx}'], +}; diff --git a/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json b/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json new file mode 100644 index 000000000..84d0d542f --- /dev/null +++ b/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "downlevelIteration": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "skipLibCheck": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "types": ["react/experimental"], + "jsx": "react-jsx" + } +} diff --git a/e2e/monorepo.spec.ts b/e2e/monorepo.spec.ts new file mode 100644 index 000000000..a78074222 --- /dev/null +++ b/e2e/monorepo.spec.ts @@ -0,0 +1,81 @@ +import { debugChildProcess, getFreePort, terminate, test } from './utils.js'; +import { fileURLToPath } from 'node:url'; +import { cp, mkdtemp } from 'node:fs/promises'; +import { exec, execSync } from 'node:child_process'; +import { expect } from '@playwright/test'; +import waitPort from 'wait-port'; +import { join } from 'node:path'; +import { tmpdir } from 'node:os'; +import { createRequire } from 'node:module'; + +let standaloneDir: string; +let standaloneAppDir: string; +const appRelativePath = '/packages/waku-project'; +const exampleDir = fileURLToPath( + new URL('./fixtures/monorepo', import.meta.url), +); +const wakuDir = fileURLToPath(new URL('../packages/waku', import.meta.url)); +const { version } = createRequire(import.meta.url)( + join(wakuDir, 'package.json'), +); + +async function start() { + const port = await getFreePort(); + const cp = exec( + `node ${join(standaloneDir, './node_modules/waku/dist/cli.js')} start --port ${port}`, + { cwd: standaloneDir }, + ); + debugChildProcess(cp, fileURLToPath(import.meta.url), [ + /ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any time/, + ]); + + await waitPort({ port }); + return [port, cp.pid] as const; +} + +test.describe('monorepo', async () => { + test.beforeEach(async () => { + // GitHub Action on Windows doesn't support mkdtemp on global temp dir, + // Which will cause files in `src` folder to be empty. + // I don't know why + const tmpDir = process.env.TEMP_DIR ? process.env.TEMP_DIR : tmpdir(); + standaloneDir = await mkdtemp(join(tmpDir, 'waku-monorepo-')); + standaloneAppDir = join(standaloneDir, appRelativePath); + await cp(exampleDir, standaloneDir, { + filter: (src) => { + return !src.includes('node_modules') && !src.includes('dist'); + }, + recursive: true, + }); + + // FIXME we need to `npm install` in the monorepo but + // how do we copy in the local version of waku or link + // it in a way that will accurately match what happens + // with the npm published version. + execSync(`pnpm pack --pack-destination ${standaloneDir}`, { + cwd: wakuDir, + stdio: 'inherit', + }); + const name = `waku-${version}.tgz`; + execSync(`npm install ${join(standaloneDir, name)}`, { + cwd: standaloneDir, + stdio: 'inherit', + }); + execSync( + `node ${join(standaloneDir, './node_modules/waku/dist/cli.js')} build`, + { + cwd: standaloneAppDir, + stdio: 'inherit', + }, + ); + }); + + test.describe('renders', () => { + test(`the home page`, async ({ page }) => { + const [port, pid] = await start(); + await page.goto(`http://localhost:${port}`); + await expect(page.getByTestId('header')).toHaveText('Waku'); + await terminate(pid!); + }); + }); +}); From 7412111c40049e4d31d911bc6f274178ee2660bc Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 02:58:21 -0500 Subject: [PATCH 02/10] Add monorepo packageDir param to startApp e2e util --- e2e/monorepo.spec.ts | 82 +++++++------------------------------------- e2e/utils.ts | 8 ++--- pnpm-lock.yaml | 2 ++ 3 files changed, 18 insertions(+), 74 deletions(-) diff --git a/e2e/monorepo.spec.ts b/e2e/monorepo.spec.ts index a78074222..9887dba3d 100644 --- a/e2e/monorepo.spec.ts +++ b/e2e/monorepo.spec.ts @@ -1,81 +1,23 @@ -import { debugChildProcess, getFreePort, terminate, test } from './utils.js'; -import { fileURLToPath } from 'node:url'; -import { cp, mkdtemp } from 'node:fs/promises'; -import { exec, execSync } from 'node:child_process'; import { expect } from '@playwright/test'; -import waitPort from 'wait-port'; -import { join } from 'node:path'; -import { tmpdir } from 'node:os'; -import { createRequire } from 'node:module'; -let standaloneDir: string; -let standaloneAppDir: string; -const appRelativePath = '/packages/waku-project'; -const exampleDir = fileURLToPath( - new URL('./fixtures/monorepo', import.meta.url), -); -const wakuDir = fileURLToPath(new URL('../packages/waku', import.meta.url)); -const { version } = createRequire(import.meta.url)( - join(wakuDir, 'package.json'), -); +import { test, prepareStandaloneSetup } from './utils.js'; -async function start() { - const port = await getFreePort(); - const cp = exec( - `node ${join(standaloneDir, './node_modules/waku/dist/cli.js')} start --port ${port}`, - { cwd: standaloneDir }, - ); - debugChildProcess(cp, fileURLToPath(import.meta.url), [ - /ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any time/, - ]); +const startApp = prepareStandaloneSetup('monorepo'); - await waitPort({ port }); - return [port, cp.pid] as const; -} - -test.describe('monorepo', async () => { - test.beforeEach(async () => { - // GitHub Action on Windows doesn't support mkdtemp on global temp dir, - // Which will cause files in `src` folder to be empty. - // I don't know why - const tmpDir = process.env.TEMP_DIR ? process.env.TEMP_DIR : tmpdir(); - standaloneDir = await mkdtemp(join(tmpDir, 'waku-monorepo-')); - standaloneAppDir = join(standaloneDir, appRelativePath); - await cp(exampleDir, standaloneDir, { - filter: (src) => { - return !src.includes('node_modules') && !src.includes('dist'); - }, - recursive: true, - }); - - // FIXME we need to `npm install` in the monorepo but - // how do we copy in the local version of waku or link - // it in a way that will accurately match what happens - // with the npm published version. - execSync(`pnpm pack --pack-destination ${standaloneDir}`, { - cwd: wakuDir, - stdio: 'inherit', +for (const mode of ['DEV', 'PRD'] as const) { + test.describe(`monorepo: ${mode}`, () => { + let port: number; + let stopApp: () => Promise; + test.beforeAll(async () => { + ({ port, stopApp } = await startApp(mode, "packages/waku-project")); }); - const name = `waku-${version}.tgz`; - execSync(`npm install ${join(standaloneDir, name)}`, { - cwd: standaloneDir, - stdio: 'inherit', + test.afterAll(async () => { + await stopApp(); }); - execSync( - `node ${join(standaloneDir, './node_modules/waku/dist/cli.js')} build`, - { - cwd: standaloneAppDir, - stdio: 'inherit', - }, - ); - }); - test.describe('renders', () => { - test(`the home page`, async ({ page }) => { - const [port, pid] = await start(); + test('renders the home page', async ({ page }) => { await page.goto(`http://localhost:${port}`); await expect(page.getByTestId('header')).toHaveText('Waku'); - await terminate(pid!); }); }); -}); +} diff --git a/e2e/utils.ts b/e2e/utils.ts index 0b4df5fb8..061b405f5 100644 --- a/e2e/utils.ts +++ b/e2e/utils.ts @@ -151,7 +151,7 @@ export const prepareStandaloneSetup = (fixtureName: string) => { const tmpDir = process.env.TEMP_DIR || tmpdir(); let standaloneDir: string | undefined; let built = false; - const startApp = async (mode: 'DEV' | 'PRD' | 'STATIC') => { + const startApp = async (mode: 'DEV' | 'PRD' | 'STATIC', packageDir = '') => { if (!standaloneDir) { standaloneDir = mkdtempSync(join(tmpDir, fixtureName)); cpSync(fixtureDir, standaloneDir, { @@ -170,10 +170,10 @@ export const prepareStandaloneSetup = (fixtureName: string) => { ); } if (mode !== 'DEV' && !built) { - rmSync(`${standaloneDir}/dist`, { recursive: true, force: true }); + rmSync(`${standaloneDir}${packageDir}/dist`, { recursive: true, force: true }); execSync( `node ${join(standaloneDir, './node_modules/waku/dist/cli.js')} build`, - { cwd: standaloneDir }, + { cwd: join(standaloneDir, packageDir) }, ); built = true; } @@ -190,7 +190,7 @@ export const prepareStandaloneSetup = (fixtureName: string) => { cmd = `node ${join(standaloneDir, './node_modules/serve/build/main.js')} dist/public -p ${port}`; break; } - const cp = exec(cmd, { cwd: standaloneDir }); + const cp = exec(cmd, { cwd: join(standaloneDir, packageDir) }); debugChildProcess(cp, fileURLToPath(import.meta.url), [ /ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any time/, ]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8699f989b..21408f93e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -175,6 +175,8 @@ importers: specifier: ^5.7.2 version: 5.7.2 + e2e/fixtures/monorepo: {} + e2e/fixtures/partial-build: dependencies: react: From 503be50e8109298c33f2df0c44f9a8c0f5ea3dcd Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 09:39:22 -0500 Subject: [PATCH 03/10] Prettier --- .../monorepo/packages/waku-project/src/pages/index.tsx | 4 +++- e2e/monorepo.spec.ts | 2 +- e2e/utils.ts | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx index 637efc9c8..6a825dd7d 100644 --- a/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx +++ b/e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx @@ -8,7 +8,9 @@ export default async function HomePage() { return (
{data.title} -

{data.headline}

+

+ {data.headline} +

{data.body}

diff --git a/e2e/monorepo.spec.ts b/e2e/monorepo.spec.ts index 9887dba3d..42072ae4f 100644 --- a/e2e/monorepo.spec.ts +++ b/e2e/monorepo.spec.ts @@ -9,7 +9,7 @@ for (const mode of ['DEV', 'PRD'] as const) { let port: number; let stopApp: () => Promise; test.beforeAll(async () => { - ({ port, stopApp } = await startApp(mode, "packages/waku-project")); + ({ port, stopApp } = await startApp(mode, 'packages/waku-project')); }); test.afterAll(async () => { await stopApp(); diff --git a/e2e/utils.ts b/e2e/utils.ts index 061b405f5..d0727b990 100644 --- a/e2e/utils.ts +++ b/e2e/utils.ts @@ -170,7 +170,10 @@ export const prepareStandaloneSetup = (fixtureName: string) => { ); } if (mode !== 'DEV' && !built) { - rmSync(`${standaloneDir}${packageDir}/dist`, { recursive: true, force: true }); + rmSync(`${standaloneDir}${packageDir}/dist`, { + recursive: true, + force: true, + }); execSync( `node ${join(standaloneDir, './node_modules/waku/dist/cli.js')} build`, { cwd: join(standaloneDir, packageDir) }, From 63d1e33e6512032badb82f7b29bbb53fba5688bc Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 15:19:54 -0500 Subject: [PATCH 04/10] eslint ignore import error --- .../monorepo/packages/waku-project/src/components/counter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx b/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx index c5b5e13a3..adb6b94e9 100644 --- a/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx +++ b/e2e/fixtures/monorepo/packages/waku-project/src/components/counter.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { useState } from 'react'; // eslint-disable-line import/no-unresolved export const Counter = () => { const [count, setCount] = useState(0); From 3bc75dc07cf7151222ff99e5175dc0d9369b06b1 Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 15:37:13 -0500 Subject: [PATCH 05/10] Fix tests --- e2e/fixtures/monorepo/packages/waku-project/tsconfig.json | 5 ++++- tsconfig.e2e.json | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json b/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json index 84d0d542f..0d0f8993d 100644 --- a/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json +++ b/e2e/fixtures/monorepo/packages/waku-project/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "composite": true, "strict": true, "target": "esnext", "downlevelIteration": true, @@ -10,6 +11,8 @@ "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "types": ["react/experimental"], - "jsx": "react-jsx" + "jsx": "react-jsx", + "rootDir": "./src", + "outDir": "./dist" } } diff --git a/tsconfig.e2e.json b/tsconfig.e2e.json index 9ec7e2831..1845263d0 100644 --- a/tsconfig.e2e.json +++ b/tsconfig.e2e.json @@ -51,6 +51,9 @@ { "path": "./e2e/fixtures/hot-reload/tsconfig.json" }, + { + "path": "./e2e/fixtures/monorepo/packages/waku-project/tsconfig.json" + }, { "path": "./e2e/fixtures/create-pages/tsconfig.json" } From 358f71dcee6c86ff5752ee2f0a306da5e4dccb0e Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 15:58:16 -0500 Subject: [PATCH 06/10] Incorporate #1101 --- e2e/monorepo.spec.ts | 28 +++++++++++++++------------- e2e/utils.ts | 11 ++++++++++- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/e2e/monorepo.spec.ts b/e2e/monorepo.spec.ts index 42072ae4f..430fc1639 100644 --- a/e2e/monorepo.spec.ts +++ b/e2e/monorepo.spec.ts @@ -5,19 +5,21 @@ import { test, prepareStandaloneSetup } from './utils.js'; const startApp = prepareStandaloneSetup('monorepo'); for (const mode of ['DEV', 'PRD'] as const) { - test.describe(`monorepo: ${mode}`, () => { - let port: number; - let stopApp: () => Promise; - test.beforeAll(async () => { - ({ port, stopApp } = await startApp(mode, 'packages/waku-project')); - }); - test.afterAll(async () => { - await stopApp(); - }); + for (const packageManager of ['npm', 'pnpm', 'yarn'] as const) { + test.describe(`monorepo: ${mode}`, () => { + let port: number; + let stopApp: () => Promise; + test.beforeAll(async () => { + ({ port, stopApp } = await startApp(mode, packageManager, 'packages/waku-project')); + }); + test.afterAll(async () => { + await stopApp(); + }); - test('renders the home page', async ({ page }) => { - await page.goto(`http://localhost:${port}`); - await expect(page.getByTestId('header')).toHaveText('Waku'); + test('renders the home page', async ({ page }) => { + await page.goto(`http://localhost:${port}`); + await expect(page.getByTestId('header')).toHaveText('Waku'); + }); }); - }); + } } diff --git a/e2e/utils.ts b/e2e/utils.ts index d0727b990..f1bcf68ca 100644 --- a/e2e/utils.ts +++ b/e2e/utils.ts @@ -138,6 +138,12 @@ export const prepareNormalSetup = (fixtureName: string) => { return startApp; }; +const PACKAGE_INSTALL = { + npm: (path: string) => `npm add ${path}`, + pnpm: (path: string) => `pnpm add ${path}`, + yarn: (path: string) => `yarn add ${path}`, +} as const; + export const prepareStandaloneSetup = (fixtureName: string) => { const wakuDir = fileURLToPath(new URL('../packages/waku', import.meta.url)); const { version } = createRequire(import.meta.url)( @@ -151,7 +157,7 @@ export const prepareStandaloneSetup = (fixtureName: string) => { const tmpDir = process.env.TEMP_DIR || tmpdir(); let standaloneDir: string | undefined; let built = false; - const startApp = async (mode: 'DEV' | 'PRD' | 'STATIC', packageDir = '') => { + const startApp = async (mode: 'DEV' | 'PRD' | 'STATIC', packageManager: 'npm' | 'pnpm' | 'yarn' = 'npm', packageDir = '') => { if (!standaloneDir) { standaloneDir = mkdtempSync(join(tmpDir, fixtureName)); cpSync(fixtureDir, standaloneDir, { @@ -164,6 +170,9 @@ export const prepareStandaloneSetup = (fixtureName: string) => { cwd: wakuDir, stdio: 'inherit', }); + const wakuPackageTgz = join(standaloneDir, `waku-${version}.tgz`); + const installScript = PACKAGE_INSTALL[packageManager](wakuPackageTgz); + execSync(installScript, { cwd: standaloneDir, stdio: 'inherit' }); execSync( `npm install --force ${join(standaloneDir, `waku-${version}.tgz`)}`, { cwd: standaloneDir, stdio: 'inherit' }, From b8863c000f1c0454e4ab79811b7d35c5a688b042 Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 16:00:05 -0500 Subject: [PATCH 07/10] Prettier --- e2e/monorepo.spec.ts | 6 +++++- e2e/utils.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/e2e/monorepo.spec.ts b/e2e/monorepo.spec.ts index 430fc1639..ce8bab33d 100644 --- a/e2e/monorepo.spec.ts +++ b/e2e/monorepo.spec.ts @@ -10,7 +10,11 @@ for (const mode of ['DEV', 'PRD'] as const) { let port: number; let stopApp: () => Promise; test.beforeAll(async () => { - ({ port, stopApp } = await startApp(mode, packageManager, 'packages/waku-project')); + ({ port, stopApp } = await startApp( + mode, + packageManager, + 'packages/waku-project', + )); }); test.afterAll(async () => { await stopApp(); diff --git a/e2e/utils.ts b/e2e/utils.ts index f1bcf68ca..00232125d 100644 --- a/e2e/utils.ts +++ b/e2e/utils.ts @@ -157,7 +157,11 @@ export const prepareStandaloneSetup = (fixtureName: string) => { const tmpDir = process.env.TEMP_DIR || tmpdir(); let standaloneDir: string | undefined; let built = false; - const startApp = async (mode: 'DEV' | 'PRD' | 'STATIC', packageManager: 'npm' | 'pnpm' | 'yarn' = 'npm', packageDir = '') => { + const startApp = async ( + mode: 'DEV' | 'PRD' | 'STATIC', + packageManager: 'npm' | 'pnpm' | 'yarn' = 'npm', + packageDir = '', + ) => { if (!standaloneDir) { standaloneDir = mkdtempSync(join(tmpDir, fixtureName)); cpSync(fixtureDir, standaloneDir, { From 3593a4ea92aa3f3ee082b25682602d777585623d Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Sun, 5 Jan 2025 17:25:40 -0500 Subject: [PATCH 08/10] Add packageManager to monorepo test name --- e2e/monorepo.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/monorepo.spec.ts b/e2e/monorepo.spec.ts index ce8bab33d..dbeec7620 100644 --- a/e2e/monorepo.spec.ts +++ b/e2e/monorepo.spec.ts @@ -6,7 +6,7 @@ const startApp = prepareStandaloneSetup('monorepo'); for (const mode of ['DEV', 'PRD'] as const) { for (const packageManager of ['npm', 'pnpm', 'yarn'] as const) { - test.describe(`monorepo: ${mode}`, () => { + test.describe(`${packageManager} monorepo: ${mode}`, () => { let port: number; let stopApp: () => Promise; test.beforeAll(async () => { From f9efa608fe9a2a601afe0c72e4b035d7fce9f326 Mon Sep 17 00:00:00 2001 From: Rob Marscher Date: Mon, 6 Jan 2025 00:01:29 -0500 Subject: [PATCH 09/10] Use join instead of string concat --- e2e/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/utils.ts b/e2e/utils.ts index 00232125d..f369eb0bf 100644 --- a/e2e/utils.ts +++ b/e2e/utils.ts @@ -183,7 +183,7 @@ export const prepareStandaloneSetup = (fixtureName: string) => { ); } if (mode !== 'DEV' && !built) { - rmSync(`${standaloneDir}${packageDir}/dist`, { + rmSync(`${join(standaloneDir, packageDir, 'dist')}`, { recursive: true, force: true, }); From 91db8bb8559d425a84c1e4c6fc0877dc768191bb Mon Sep 17 00:00:00 2001 From: Daishi Kato Date: Tue, 7 Jan 2025 08:12:10 +0900 Subject: [PATCH 10/10] Delete e2e/fixtures/monorepo/packages/waku-project/.gitignore --- e2e/fixtures/monorepo/packages/waku-project/.gitignore | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 e2e/fixtures/monorepo/packages/waku-project/.gitignore diff --git a/e2e/fixtures/monorepo/packages/waku-project/.gitignore b/e2e/fixtures/monorepo/packages/waku-project/.gitignore deleted file mode 100644 index ad583432d..000000000 --- a/e2e/fixtures/monorepo/packages/waku-project/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -node_modules -dist -.env* -*.tsbuildinfo -.cache -.DS_Store -*.pem