From e851c66e0b51aad6fa04c677f285b6cf0484615b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8Leonardo?= <¨negreirosleo12@gmail.com¨> Date: Thu, 2 May 2024 22:03:53 -0300 Subject: [PATCH] test: add e2e tests for css modules --- e2e/fixtures/rsc-css-modules/README.md | 3 + e2e/fixtures/rsc-css-modules/package.json | 22 ++++++ .../rsc-css-modules/src/components/App.tsx | 16 ++++ .../src/components/ClientCounter.tsx | 20 +++++ .../src/components/app.module.css | 9 +++ .../src/components/clientCounter.module.css | 9 +++ e2e/fixtures/rsc-css-modules/src/entries.tsx | 19 +++++ e2e/fixtures/rsc-css-modules/src/main.tsx | 13 ++++ e2e/fixtures/rsc-css-modules/tsconfig.json | 17 ++++ e2e/fixtures/rsc-css-modules/waku.config.ts | 16 ++++ e2e/rsc-css-modules.spec.ts | 77 +++++++++++++++++++ pnpm-lock.yaml | 27 ++++++- 12 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 e2e/fixtures/rsc-css-modules/README.md create mode 100644 e2e/fixtures/rsc-css-modules/package.json create mode 100644 e2e/fixtures/rsc-css-modules/src/components/App.tsx create mode 100644 e2e/fixtures/rsc-css-modules/src/components/ClientCounter.tsx create mode 100644 e2e/fixtures/rsc-css-modules/src/components/app.module.css create mode 100644 e2e/fixtures/rsc-css-modules/src/components/clientCounter.module.css create mode 100644 e2e/fixtures/rsc-css-modules/src/entries.tsx create mode 100644 e2e/fixtures/rsc-css-modules/src/main.tsx create mode 100644 e2e/fixtures/rsc-css-modules/tsconfig.json create mode 100644 e2e/fixtures/rsc-css-modules/waku.config.ts create mode 100644 e2e/rsc-css-modules.spec.ts diff --git a/e2e/fixtures/rsc-css-modules/README.md b/e2e/fixtures/rsc-css-modules/README.md new file mode 100644 index 000000000..088740a69 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/README.md @@ -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. diff --git a/e2e/fixtures/rsc-css-modules/package.json b/e2e/fixtures/rsc-css-modules/package.json new file mode 100644 index 000000000..62586aa71 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/package.json @@ -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.2.74", + "@types/react-dom": "18.2.24", + "typescript": "5.4.4" + } +} diff --git a/e2e/fixtures/rsc-css-modules/src/components/App.tsx b/e2e/fixtures/rsc-css-modules/src/components/App.tsx new file mode 100644 index 000000000..74d730263 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/src/components/App.tsx @@ -0,0 +1,16 @@ +import styles from './app.module.css'; +import { ClientCounter } from './ClientCounter.js'; + +const App = ({ name }: { name: string }) => { + return ( +
+ Waku example +

+ {name} +

+ +
+ ); +}; + +export default App; diff --git a/e2e/fixtures/rsc-css-modules/src/components/ClientCounter.tsx b/e2e/fixtures/rsc-css-modules/src/components/ClientCounter.tsx new file mode 100644 index 000000000..731cc2f6b --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/src/components/ClientCounter.tsx @@ -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 ( +
+

{count}

+ +
+ ); +}; diff --git a/e2e/fixtures/rsc-css-modules/src/components/app.module.css b/e2e/fixtures/rsc-css-modules/src/components/app.module.css new file mode 100644 index 000000000..68d6e759c --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/src/components/app.module.css @@ -0,0 +1,9 @@ +.wrapper { + display: flex; + flex-direction: column; +} + +.text { + font-size: 18px; + color: blue; +} diff --git a/e2e/fixtures/rsc-css-modules/src/components/clientCounter.module.css b/e2e/fixtures/rsc-css-modules/src/components/clientCounter.module.css new file mode 100644 index 000000000..af2190d17 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/src/components/clientCounter.module.css @@ -0,0 +1,9 @@ +.counterWrapper { + display: flex; + flex-direction: row; + gap: 4px; +} + +.counterButton { + padding: 8px; +} diff --git a/e2e/fixtures/rsc-css-modules/src/entries.tsx b/e2e/fixtures/rsc-css-modules/src/entries.tsx new file mode 100644 index 000000000..00cd7ab33 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/src/entries.tsx @@ -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: , + }; + }, + // getBuildConfig + async () => [{ pathname: '/', entries: [{ input: '' }] }], + // getSsrConfig + () => { + throw new Error('SSR should not be used in this test.'); + }, +); diff --git a/e2e/fixtures/rsc-css-modules/src/main.tsx b/e2e/fixtures/rsc-css-modules/src/main.tsx new file mode 100644 index 000000000..057e44a90 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/src/main.tsx @@ -0,0 +1,13 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import { Root, Slot } from 'waku/client'; + +const rootElement = ( + + + + + +); + +createRoot(document.body).render(rootElement); diff --git a/e2e/fixtures/rsc-css-modules/tsconfig.json b/e2e/fixtures/rsc-css-modules/tsconfig.json new file mode 100644 index 000000000..020580766 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/tsconfig.json @@ -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"] +} diff --git a/e2e/fixtures/rsc-css-modules/waku.config.ts b/e2e/fixtures/rsc-css-modules/waku.config.ts new file mode 100644 index 000000000..419997de7 --- /dev/null +++ b/e2e/fixtures/rsc-css-modules/waku.config.ts @@ -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'), + ], +}; diff --git a/e2e/rsc-css-modules.spec.ts b/e2e/rsc-css-modules.spec.ts new file mode 100644 index 000000000..721259593 --- /dev/null +++ b/e2e/rsc-css-modules.spec.ts @@ -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'); + }); + }); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4045e292a..b9bf3b83c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -125,6 +125,31 @@ importers: specifier: 5.4.4 version: 5.4.4 + e2e/fixtures/rsc-css-modules: + dependencies: + react: + specifier: 19.0.0-beta-4508873393-20240430 + version: 19.0.0-beta-4508873393-20240430 + react-dom: + specifier: 19.0.0-beta-4508873393-20240430 + version: 19.0.0-beta-4508873393-20240430(react@19.0.0-beta-4508873393-20240430) + react-server-dom-webpack: + specifier: 19.0.0-beta-4508873393-20240430 + version: 19.0.0-beta-4508873393-20240430(react-dom@19.0.0-beta-4508873393-20240430)(react@19.0.0-beta-4508873393-20240430)(webpack@5.91.0) + waku: + specifier: workspace:* + version: link:../../../packages/waku + devDependencies: + '@types/react': + specifier: 18.2.74 + version: 18.2.74 + '@types/react-dom': + specifier: 18.2.24 + version: 18.2.24 + typescript: + specifier: 5.4.4 + version: 5.4.4 + e2e/fixtures/rsc-router: dependencies: react: @@ -2443,7 +2468,7 @@ packages: /@vanilla-extract/vite-plugin@4.0.7(@types/node@20.12.5)(vite@5.2.8): resolution: {integrity: sha512-uRAFWdq5Eq0ybpgW2P0LNOw8eW+MTg/OFo5K0Hsl2cKu/Tu2tabCsBf6vNjfhDrm4jBShHy1wJIVcYxf6sczVQ==} peerDependencies: - vite: ^4.0.3 || ^5.0.0 + vite: 5.2.8 dependencies: '@vanilla-extract/integration': 7.1.2(@types/node@20.12.5) vite: 5.2.8(@types/node@20.12.5)