Skip to content

Commit

Permalink
test: add e2e tests for css modules (#693)
Browse files Browse the repository at this point in the history
This PR relates to #186. It adds e2e tests for CSS modules.
I used `expect .toContain('class-name')` because I was not sure if the
generated name would always be the same.

---------

Co-authored-by: ¨Leonardo <¨[email protected]¨>
Co-authored-by: Daishi Kato <[email protected]>
  • Loading branch information
3 people authored May 4, 2024
1 parent c04f94a commit c41ef0c
Show file tree
Hide file tree
Showing 14 changed files with 250 additions and 0 deletions.
3 changes: 3 additions & 0 deletions e2e/fixtures/rsc-css-modules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# RSC CSS Modules

Only RSC features, no SSR. Using css modules to style the application, both on server and client components.
1 change: 1 addition & 0 deletions e2e/fixtures/rsc-css-modules/declaration.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module '*.module.css';
22 changes: 22 additions & 0 deletions e2e/fixtures/rsc-css-modules/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "rsc-css-modules",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"dev": "waku dev",
"build": "waku build",
"start": "waku start"
},
"dependencies": {
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430",
"react-server-dom-webpack": "19.0.0-beta-4508873393-20240430",
"waku": "workspace:*"
},
"devDependencies": {
"@types/react": "18.3.1",
"@types/react-dom": "18.3.0",
"typescript": "5.4.4"
}
}
16 changes: 16 additions & 0 deletions e2e/fixtures/rsc-css-modules/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styles from './app.module.css';
import { ClientCounter } from './ClientCounter.js';

const App = ({ name }: { name: string }) => {
return (
<div data-testid="app-wrapper" className={styles.wrapper}>
<title>Waku example</title>
<p className={styles.text} data-testid="app-name">
{name}
</p>
<ClientCounter />
</div>
);
};

export default App;
20 changes: 20 additions & 0 deletions e2e/fixtures/rsc-css-modules/src/components/ClientCounter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client';
import { useState } from 'react';
import styles from './clientCounter.module.css';

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

return (
<div className={styles.counterWrapper} data-testid="client-counter">
<p data-testid="count">{count}</p>
<button
className={styles.counterButton}
data-testid="increment"
onClick={() => setCount((c) => c + 1)}
>
Increment
</button>
</div>
);
};
9 changes: 9 additions & 0 deletions e2e/fixtures/rsc-css-modules/src/components/app.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.wrapper {
display: flex;
flex-direction: column;
}

.text {
font-size: 18px;
color: blue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.counterWrapper {
display: flex;
flex-direction: row;
gap: 4px;
}

.counterButton {
padding: 8px;
}
19 changes: 19 additions & 0 deletions e2e/fixtures/rsc-css-modules/src/entries.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { lazy } from 'react';
import { defineEntries } from 'waku/server';

const App = lazy(() => import('./components/App.js'));

export default defineEntries(
// renderEntries
async (input) => {
return {
App: <App name={input || 'Waku'} />,
};
},
// getBuildConfig
async () => [{ pathname: '/', entries: [{ input: '' }] }],
// getSsrConfig
() => {
throw new Error('SSR should not be used in this test.');
},
);
13 changes: 13 additions & 0 deletions e2e/fixtures/rsc-css-modules/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Root, Slot } from 'waku/client';

const rootElement = (
<StrictMode>
<Root>
<Slot id="App" />
</Root>
</StrictMode>
);

createRoot(document.body).render(rootElement);
17 changes: 17 additions & 0 deletions e2e/fixtures/rsc-css-modules/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"strict": true,
"target": "esnext",
"downlevelIteration": true,
"esModuleInterop": true,
"module": "nodenext",
"skipLibCheck": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"types": ["react/experimental"],
"jsx": "react-jsx",
"outDir": "./dist",
"composite": true
},
"include": ["./src", "./waku.config.ts", "declaration.d.ts"]
}
16 changes: 16 additions & 0 deletions e2e/fixtures/rsc-css-modules/waku.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const DO_NOT_BUNDLE = '';

/** @type {import('waku/config').Config} */
export default {
middleware: (cmd: 'dev' | 'start') => [
...(cmd === 'dev'
? [
import(
/* @vite-ignore */ DO_NOT_BUNDLE + 'waku/middleware/dev-server'
),
]
: []),
import('waku/middleware/rsc'),
import('waku/middleware/fallback'),
],
};
77 changes: 77 additions & 0 deletions e2e/rsc-css-modules.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { expect } from '@playwright/test';
import { execSync, exec, ChildProcess } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import waitPort from 'wait-port';
import { debugChildProcess, getFreePort, terminate, test } from './utils.js';
import { rm } from 'node:fs/promises';

const waku = fileURLToPath(
new URL('../packages/waku/dist/cli.js', import.meta.url),
);

const commands = [
{
command: 'dev',
},
{
build: 'build',
command: 'start',
},
];

const cwd = fileURLToPath(
new URL('./fixtures/rsc-css-modules', import.meta.url),
);

for (const { build, command } of commands) {
test.describe(`rsc-css-modules: ${command}`, () => {
let cp: ChildProcess;
let port: number;
test.beforeAll('remove cache', async () => {
await rm(`${cwd}/dist`, {
recursive: true,
force: true,
});
});

test.beforeAll(async () => {
if (build) {
execSync(`node ${waku} ${build}`, { cwd });
}
port = await getFreePort();
cp = exec(`node ${waku} ${command} --port ${port}`, { cwd });
debugChildProcess(cp, fileURLToPath(import.meta.url), [
/ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any time/,
]);
await waitPort({ port });
});

test.afterAll(async () => {
await terminate(cp.pid!);
});

test('css-modules classes', async ({ page }) => {
await page.goto(`http://localhost:${port}/`);

const wrapperClass = await page
.getByTestId('app-wrapper')
.getAttribute('class');
expect(wrapperClass).toContain('wrapper');

const appNameClass = await page
.getByTestId('app-name')
.getAttribute('class');
expect(appNameClass).toContain('text');

const clientcounterClass = await page
.getByTestId('client-counter')
.getAttribute('class');
expect(clientcounterClass).toContain('counterWrapper');

const incrementClass = await page
.getByTestId('increment')
.getAttribute('class');
expect(incrementClass).toContain('counterButton');
});
});
}
25 changes: 25 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 @@ -9,6 +9,9 @@
{
"path": "./e2e/fixtures/rsc-basic/tsconfig.json"
},
{
"path": "./e2e/fixtures/rsc-css-modules/tsconfig.json"
},
{
"path": "./e2e/fixtures/ssr-basic/tsconfig.json"
},
Expand Down

0 comments on commit c41ef0c

Please sign in to comment.