Skip to content

Commit

Permalink
chore: create monorepo e2e spec (#1079)
Browse files Browse the repository at this point in the history
This needs more work to figure out how to install dependencies in the
test monorepo and link in the waku package in a way that closely matches
the way it works with published npm packages.

---------

Co-authored-by: Daishi Kato <[email protected]>
  • Loading branch information
rmarscher and dai-shi authored Jan 6, 2025
1 parent 52f7ad6 commit de3a3c6
Show file tree
Hide file tree
Showing 17 changed files with 275 additions and 4 deletions.
7 changes: 7 additions & 0 deletions e2e/fixtures/monorepo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "monorepo",
"private": true,
"workspaces": [
"packages/*"
]
}
23 changes: 23 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
7 changes: 7 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('postcss-load-config').Config} */
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import { useState } from 'react'; // eslint-disable-line import/no-unresolved

export const Counter = () => {
const [count, setCount] = useState(0);

const handleIncrement = () => setCount((c) => c + 1);

return (
<section className="border-blue-400 -mx-4 mt-4 rounded border border-dashed p-4">
<div>Count: {count}</div>
<button
onClick={handleIncrement}
className="rounded-sm bg-black px-2 py-0.5 text-sm text-white"
>
Increment
</button>
</section>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const Footer = () => {
return (
<footer className="p-6 lg:fixed lg:bottom-0 lg:left-0">
<div>
visit{' '}
<a
href="https://waku.gg/"
target="_blank"
rel="noreferrer"
className="mt-4 inline-block underline"
>
waku.gg
</a>{' '}
to learn more
</div>
</footer>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Link } from 'waku';

export const Header = () => {
return (
<header className="flex items-center gap-4 p-6 lg:fixed lg:left-0 lg:top-0">
<h2 className="text-lg font-bold tracking-tight">
<Link to="/">Waku starter</Link>
</h2>
</header>
);
};
39 changes: 39 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/src/pages/_layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="font-['Nunito']">
<meta name="description" content={data.description} />
<link rel="icon" type="image/png" href={data.icon} />
<Header />
<main className="m-6 flex items-center *:min-h-64 *:min-w-64 lg:m-0 lg:min-h-svh lg:justify-center">
{children}
</main>
<Footer />
</div>
);
}

const getData = async () => {
const data = {
description: 'An internet website!',
icon: '/images/favicon.png',
};

return data;
};

export const getConfig = async () => {
return {
render: 'static',
} as const;
};
32 changes: 32 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/src/pages/about.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Link } from 'waku';

export default async function AboutPage() {
const data = await getData();

return (
<div>
<title>{data.title}</title>
<h1 className="text-4xl font-bold tracking-tight">{data.headline}</h1>
<p>{data.body}</p>
<Link to="/" className="mt-4 inline-block underline">
Return home
</Link>
</div>
);
}

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;
};
37 changes: 37 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Link } from 'waku';

import { Counter } from '../components/counter';

export default async function HomePage() {
const data = await getData();

return (
<div>
<title>{data.title}</title>
<h1 className="text-4xl font-bold tracking-tight" data-testid="header">
{data.headline}
</h1>
<p>{data.body}</p>
<Counter />
<Link to="/about" className="mt-4 inline-block underline">
About page
</Link>
</div>
);
}

const getData = async () => {
const data = {
title: 'Waku',
headline: 'Waku',
body: 'Hello world!',
};

return data;
};

export const getConfig = async () => {
return {
render: 'static',
} as const;
};
4 changes: 4 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/src/styles.css
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
};
18 changes: 18 additions & 0 deletions e2e/fixtures/monorepo/packages/waku-project/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"composite": true,
"strict": true,
"target": "esnext",
"downlevelIteration": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"skipLibCheck": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"types": ["react/experimental"],
"jsx": "react-jsx",
"rootDir": "./src",
"outDir": "./dist"
}
}
29 changes: 29 additions & 0 deletions e2e/monorepo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { expect } from '@playwright/test';

import { test, prepareStandaloneSetup } from './utils.js';

const startApp = prepareStandaloneSetup('monorepo');

for (const mode of ['DEV', 'PRD'] as const) {
for (const packageManager of ['npm', 'pnpm', 'yarn'] as const) {
test.describe(`${packageManager} monorepo: ${mode}`, () => {
let port: number;
let stopApp: () => Promise<void>;
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');
});
});
}
}
24 changes: 20 additions & 4 deletions e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)(
Expand All @@ -151,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') => {
const startApp = async (
mode: 'DEV' | 'PRD' | 'STATIC',
packageManager: 'npm' | 'pnpm' | 'yarn' = 'npm',
packageDir = '',
) => {
if (!standaloneDir) {
standaloneDir = mkdtempSync(join(tmpDir, fixtureName));
cpSync(fixtureDir, standaloneDir, {
Expand All @@ -164,16 +174,22 @@ 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' },
);
}
if (mode !== 'DEV' && !built) {
rmSync(`${standaloneDir}/dist`, { recursive: true, force: true });
rmSync(`${join(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;
}
Expand All @@ -190,7 +206,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/,
]);
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tsconfig.e2e.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down

0 comments on commit de3a3c6

Please sign in to comment.