From 6794ab20d3244b6bdf7f61a2b97d88ab408a09f5 Mon Sep 17 00:00:00 2001 From: Jovan Milosevic <39063488+m-jovan@users.noreply.github.com> Date: Wed, 12 Feb 2025 08:57:18 +0100 Subject: [PATCH] feat: Add e2e setup and tests (#535) --- .github/workflows/e2e-ci.yml | 61 ++++++++ .gitignore | 3 +- Cargo.toml | 1 + e2e/e2e-test-setup.js | 8 + e2e/fixtures/base/.gitignore | 20 +++ e2e/fixtures/base/Cargo.toml | 13 ++ e2e/fixtures/base/package.json | 19 +++ e2e/fixtures/base/playwright.config.ts | 26 ++++ e2e/fixtures/base/src/routes/__layout.tsx | 17 +++ e2e/fixtures/base/src/routes/index.rs | 14 ++ e2e/fixtures/base/src/routes/index.tsx | 24 +++ .../base/src/routes/second-route/index.tsx | 5 + e2e/fixtures/base/src/styles/global.css | 0 e2e/fixtures/base/tests/e2e.spec.ts | 23 +++ e2e/fixtures/base/tsconfig.json | 24 +++ e2e/fixtures/base/tuono.config.ts | 5 + package.json | 4 +- pnpm-lock.yaml | 140 +++++++++++++----- pnpm-workspace.yaml | 1 + 19 files changed, 366 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/e2e-ci.yml create mode 100644 e2e/e2e-test-setup.js create mode 100644 e2e/fixtures/base/.gitignore create mode 100644 e2e/fixtures/base/Cargo.toml create mode 100644 e2e/fixtures/base/package.json create mode 100644 e2e/fixtures/base/playwright.config.ts create mode 100644 e2e/fixtures/base/src/routes/__layout.tsx create mode 100644 e2e/fixtures/base/src/routes/index.rs create mode 100644 e2e/fixtures/base/src/routes/index.tsx create mode 100644 e2e/fixtures/base/src/routes/second-route/index.tsx create mode 100644 e2e/fixtures/base/src/styles/global.css create mode 100644 e2e/fixtures/base/tests/e2e.spec.ts create mode 100644 e2e/fixtures/base/tsconfig.json create mode 100644 e2e/fixtures/base/tuono.config.ts diff --git a/.github/workflows/e2e-ci.yml b/.github/workflows/e2e-ci.yml new file mode 100644 index 00000000..088d4b73 --- /dev/null +++ b/.github/workflows/e2e-ci.yml @@ -0,0 +1,61 @@ +name: E2E CI + +on: + push: + branches: + - 'main' + pull_request: + +concurrency: + group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}' + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + e2e: + name: E2E Test (${{ matrix.os }}) + + strategy: + fail-fast: true + matrix: + os: + - 'ubuntu-latest' + - 'macos-latest' + - 'windows-latest' + + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install NodeJS Dependencies + uses: ./.github/actions/install-node-dependencies + + - name: Setup rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Install Playwright Browsers + run: pnpm exec playwright install + + - name: Run Playwright E2E tests + run: pnpm test:e2e + + ci_ok: + name: E2E CI OK + runs-on: ubuntu-latest + timeout-minutes: 1 + if: always() + needs: [e2e] + env: + FAILURE: ${{ contains(join(needs.*.result, ','), 'failure') }} + CANCELLED: ${{ contains(join(needs.*.result, ','), 'cancelled') }} + steps: + - name: Check for failure or cancelled jobs result + shell: bash + run: | + echo "Failure: $FAILURE - Cancelled: $CANCELLED" + if [ "$FAILURE" = "false" ] && [ "$CANCELLED" = "false" ]; then + exit 0 + else + exit 1 + fi diff --git a/.gitignore b/.gitignore index 10ff7e3d..f975054a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ vite.config.ts.timestamp* *.pdb # Files, generated by the code editors -.vscode/ \ No newline at end of file +.vscode/ + diff --git a/Cargo.toml b/Cargo.toml index 24b899c7..8f28bde2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ exclude = [ "examples/tuono-app", "examples/tuono-tutorial", "examples/with-tailwind", + "e2e/fixtures/base", ] diff --git a/e2e/e2e-test-setup.js b/e2e/e2e-test-setup.js new file mode 100644 index 00000000..f08bf1a8 --- /dev/null +++ b/e2e/e2e-test-setup.js @@ -0,0 +1,8 @@ +import { execSync } from 'child_process' +import path from 'path' + +const __dirname = import.meta.dirname +const rootDir = path.join(__dirname, '..') + +execSync('cargo build --config opt-level=0', { cwd: rootDir, stdio: 'inherit' }) +execSync('turbo build', { stdio: 'inherit' }) diff --git a/e2e/fixtures/base/.gitignore b/e2e/fixtures/base/.gitignore new file mode 100644 index 00000000..11b17227 --- /dev/null +++ b/e2e/fixtures/base/.gitignore @@ -0,0 +1,20 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.tuono +out +target + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ + diff --git a/e2e/fixtures/base/Cargo.toml b/e2e/fixtures/base/Cargo.toml new file mode 100644 index 00000000..71e05c3b --- /dev/null +++ b/e2e/fixtures/base/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "tuono-app" +version = "0.0.1" +edition = "2021" + +[[bin]] +name = "tuono" +path = ".tuono/main.rs" + +[dependencies] +tuono_lib = { path = "../../../crates/tuono_lib" } +serde = { version = "1.0.202", features = ["derive"] } + diff --git a/e2e/fixtures/base/package.json b/e2e/fixtures/base/package.json new file mode 100644 index 00000000..b235ca76 --- /dev/null +++ b/e2e/fixtures/base/package.json @@ -0,0 +1,19 @@ +{ + "name": "fixture-base", + "type": "module", + "description": "Basic tuono application", + "version": "0.0.1", + "scripts": { + "test:e2e": "playwright test" + }, + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tuono": "workspace:*" + }, + "devDependencies": { + "@types/react": "^19.0.2", + "@types/react-dom": "^19.0.2", + "typescript": "^5.6.3" + } +} diff --git a/e2e/fixtures/base/playwright.config.ts b/e2e/fixtures/base/playwright.config.ts new file mode 100644 index 00000000..af421cf2 --- /dev/null +++ b/e2e/fixtures/base/playwright.config.ts @@ -0,0 +1,26 @@ +import * as path from 'path' + +import { defineConfig } from '@playwright/test' + +const __dirname = import.meta.dirname + +const tuonoDir = path.join(__dirname, '../../../', 'target', 'debug', 'tuono') +const setupScript = path.join(__dirname, '../..', 'e2e-test-setup.js') + +export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + webServer: { + command: `node ${setupScript} && ${tuonoDir} dev`, + port: 3000, + timeout: 420 * 1000, + stdout: 'pipe', + reuseExistingServer: false, + }, + use: { + baseURL: 'http://localhost:3000', + }, +}) diff --git a/e2e/fixtures/base/src/routes/__layout.tsx b/e2e/fixtures/base/src/routes/__layout.tsx new file mode 100644 index 00000000..8ef43630 --- /dev/null +++ b/e2e/fixtures/base/src/routes/__layout.tsx @@ -0,0 +1,17 @@ +import type { ReactNode, JSX } from 'react' +import { TuonoScripts } from 'tuono' + +interface RootLayoutProps { + children: ReactNode +} + +export default function RootLayout({ children }: RootLayoutProps): JSX.Element { + return ( + + +
{children}
+ + + + ) +} diff --git a/e2e/fixtures/base/src/routes/index.rs b/e2e/fixtures/base/src/routes/index.rs new file mode 100644 index 00000000..72ddb9e7 --- /dev/null +++ b/e2e/fixtures/base/src/routes/index.rs @@ -0,0 +1,14 @@ +use serde::Serialize; +use tuono_lib::{Props, Request, Response}; + +#[derive(Serialize)] +struct MyResponse<'a> { + subtitle: &'a str, +} + +#[tuono_lib::handler] +async fn get_server_side_props(_req: Request) -> Response { + Response::Props(Props::new(MyResponse { + subtitle: "Subtitle received from the server", + })) +} diff --git a/e2e/fixtures/base/src/routes/index.tsx b/e2e/fixtures/base/src/routes/index.tsx new file mode 100644 index 00000000..87f3f8fe --- /dev/null +++ b/e2e/fixtures/base/src/routes/index.tsx @@ -0,0 +1,24 @@ +import type { JSX } from 'react' +import type { TuonoProps } from 'tuono' +import { Link } from 'tuono' + +interface IndexProps { + subtitle: string +} + +export default function IndexPage({ + data, + isLoading, +}: TuonoProps): JSX.Element { + if (isLoading) { + return

Loading...

+ } + + return ( + <> +

TUONO

+

{data?.subtitle}

+ Routing link) + + ) +} diff --git a/e2e/fixtures/base/src/routes/second-route/index.tsx b/e2e/fixtures/base/src/routes/second-route/index.tsx new file mode 100644 index 00000000..c746bcab --- /dev/null +++ b/e2e/fixtures/base/src/routes/second-route/index.tsx @@ -0,0 +1,5 @@ +import type { JSX } from 'react' + +export default function SecondRoute(): JSX.Element { + return

Second route

+} diff --git a/e2e/fixtures/base/src/styles/global.css b/e2e/fixtures/base/src/styles/global.css new file mode 100644 index 00000000..e69de29b diff --git a/e2e/fixtures/base/tests/e2e.spec.ts b/e2e/fixtures/base/tests/e2e.spec.ts new file mode 100644 index 00000000..9bbdd51a --- /dev/null +++ b/e2e/fixtures/base/tests/e2e.spec.ts @@ -0,0 +1,23 @@ +import { test, expect } from '@playwright/test' + +test('it renders index page', async ({ page }) => { + await page.goto('/') + const header = await page.textContent('h1') + const subtitle = await page.textContent('h2') + expect(header).toContain('TUONO') + expect(subtitle).toContain('Subtitle received from the server') +}) + +test('it renders second route', async ({ page }) => { + await page.goto('/second-route') + const header = await page.textContent('h1') + expect(header).toContain('Second route') +}) + +test('it routes to second route on link click', async ({ page }) => { + await page.goto('/') + await page.click('text=Routing link') + await page.waitForURL('/second-route') + const header = await page.textContent('h1') + expect(header).toContain('Second route') +}) diff --git a/e2e/fixtures/base/tsconfig.json b/e2e/fixtures/base/tsconfig.json new file mode 100644 index 00000000..39d76807 --- /dev/null +++ b/e2e/fixtures/base/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src", "tuono.config.ts"] +} diff --git a/e2e/fixtures/base/tuono.config.ts b/e2e/fixtures/base/tuono.config.ts new file mode 100644 index 00000000..a70b2924 --- /dev/null +++ b/e2e/fixtures/base/tuono.config.ts @@ -0,0 +1,5 @@ +import type { TuonoConfig } from 'tuono/config' + +const config: TuonoConfig = {} + +export default config diff --git a/package.json b/package.json index d7d2bf3d..73541047 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "docs:types": "turbo types --filter=documentation", "repo:root:format:check": "prettier . !./apps/** !./assets/** !./crates !./examples !./packages/** --check", "repo:root:format": "prettier . !./apps/** !./assets/** !./crates !./examples !./packages/** --write", - "check-all": "turbo build lint format:check types --filter=!./examples" + "check-all": "turbo build lint format:check types --filter=!./examples", + "test:e2e": "pnpm --filter='fixture-*' run test:e2e" }, "author": "Valerio Ageno", "license": "MIT", @@ -26,6 +27,7 @@ "@eslint/js": "9.20.0", "@types/node": "22.13.1", "eslint": "9.20.0", + "@playwright/test": "^1.50.1", "eslint-import-resolver-typescript": "3.7.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-react": "7.37.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a98cdb78..bd8f39f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@eslint/js': specifier: 9.20.0 version: 9.20.0 + '@playwright/test': + specifier: ^1.50.1 + version: 1.50.1 '@types/node': specifier: 22.13.1 version: 22.13.1 @@ -97,6 +100,28 @@ importers: specifier: 7.0.1 version: 7.0.1(postcss@8.5.1) + e2e/fixtures/base: + dependencies: + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) + tuono: + specifier: workspace:* + version: link:../../../packages/tuono + devDependencies: + '@types/react': + specifier: ^19.0.2 + version: 19.0.8 + '@types/react-dom': + specifier: ^19.0.2 + version: 19.0.3(@types/react@19.0.8) + typescript: + specifier: ^5.6.3 + version: 5.7.3 + examples/tuono-app: dependencies: react: @@ -173,7 +198,7 @@ importers: dependencies: '@tailwindcss/vite': specifier: ^4.0.0-beta.9 - version: 4.0.0-beta.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + version: 4.0.0-beta.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) react: specifier: ^19.0.0 version: 19.0.0 @@ -213,7 +238,7 @@ importers: version: 5.0.5(rollup@4.31.0) '@vitejs/plugin-react-swc': specifier: ^3.7.0 - version: 3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + version: 3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) fast-text-encoding: specifier: ^1.0.6 version: 1.0.6 @@ -228,14 +253,14 @@ importers: version: 8.2.5 vite: specifier: ^5.4.14 - version: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + version: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) web-streams-polyfill: specifier: ^4.0.0 version: 4.0.0 devDependencies: '@tanstack/config': specifier: 0.7.13 - version: 0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + version: 0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -259,7 +284,7 @@ importers: version: 19.0.0(react@19.0.0) vitest: specifier: 2.1.9 - version: 2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + version: 2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1) packages/tuono-fs-router-vite-plugin: dependencies: @@ -274,17 +299,17 @@ importers: version: 3.5.0 vite: specifier: ^5.4.14 - version: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + version: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) devDependencies: '@tanstack/config': specifier: 0.7.13 - version: 0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + version: 0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 vitest: specifier: 2.1.9 - version: 2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + version: 2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1) packages/tuono-router: dependencies: @@ -294,7 +319,7 @@ importers: devDependencies: '@tanstack/config': specifier: 0.7.13 - version: 0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + version: 0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) '@testing-library/react': specifier: 16.2.0 version: 16.2.0(@testing-library/dom@10.4.0)(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -303,7 +328,7 @@ importers: version: 19.0.8 '@vitejs/plugin-react-swc': specifier: 3.7.2 - version: 3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + version: 3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) happy-dom: specifier: 16.8.1 version: 16.8.1 @@ -312,10 +337,10 @@ importers: version: 19.0.0 vite: specifier: 5.4.14 - version: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + version: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) vitest: specifier: 2.1.9 - version: 2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + version: 2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1) packages: @@ -718,6 +743,11 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} + '@playwright/test@1.50.1': + resolution: {integrity: sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==} + engines: {node: '>=18'} + hasBin: true + '@rollup/plugin-inject@5.0.5': resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} @@ -1826,6 +1856,11 @@ packages: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2660,6 +2695,16 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + playwright-core@1.50.1: + resolution: {integrity: sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.50.1: + resolution: {integrity: sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==} + engines: {node: '>=18'} + hasBin: true + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -3918,6 +3963,10 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} + '@playwright/test@1.50.1': + dependencies: + playwright: 1.50.1 + '@rollup/plugin-inject@5.0.5(rollup@4.31.0)': dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.31.0) @@ -4137,15 +4186,15 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.0.0-beta.9 '@tailwindcss/oxide-win32-x64-msvc': 4.0.0-beta.9 - '@tailwindcss/vite@4.0.0-beta.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)))': + '@tailwindcss/vite@4.0.0-beta.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1))': dependencies: '@tailwindcss/node': 4.0.0-beta.9 '@tailwindcss/oxide': 4.0.0-beta.9 lightningcss: 1.29.1 tailwindcss: 4.0.0-beta.9 - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) - '@tanstack/config@0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)))': + '@tanstack/config@0.7.13(@types/node@22.13.1)(esbuild@0.21.5)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1))': dependencies: '@commitlint/parse': 19.5.0 commander: 12.1.0 @@ -4159,9 +4208,9 @@ snapshots: semver: 7.6.3 simple-git: 3.27.0 v8flags: 4.0.1 - vite-plugin-dts: 3.9.1(@types/node@22.13.1)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) - vite-plugin-externalize-deps: 0.8.0(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) - vite-tsconfig-paths: 4.3.2(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + vite-plugin-dts: 3.9.1(@types/node@22.13.1)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) + vite-plugin-externalize-deps: 0.8.0(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) + vite-tsconfig-paths: 4.3.2(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) transitivePeerDependencies: - '@types/node' - esbuild @@ -4345,10 +4394,10 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react-swc@3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)))': + '@vitejs/plugin-react-swc@3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1))': dependencies: '@swc/core': 1.9.3 - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) transitivePeerDependencies: - '@swc/helpers' @@ -4359,13 +4408,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)))': + '@vitest/mocker@2.1.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) '@vitest/pretty-format@2.1.9': dependencies: @@ -4946,7 +4995,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.20.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.20.0(jiti@2.4.2)))(eslint@9.20.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -4968,7 +5017,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.20.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.20.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.20.0(jiti@2.4.2)))(eslint@9.20.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -5208,6 +5257,9 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -6301,6 +6353,14 @@ snapshots: picomatch@4.0.2: {} + playwright-core@1.50.1: {} + + playwright@1.50.1: + dependencies: + playwright-core: 1.50.1 + optionalDependencies: + fsevents: 2.3.2 + possible-typed-array-names@1.0.0: {} postcss-js@4.0.1(postcss@8.5.1): @@ -6838,7 +6898,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/types': 7.26.3 prettier: 3.5.0 - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) transitivePeerDependencies: - '@types/node' - less @@ -6863,13 +6923,13 @@ snapshots: '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) '@rollup/plugin-inject': 5.0.5(rollup@4.31.0) - '@vitejs/plugin-react-swc': 3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + '@vitejs/plugin-react-swc': 3.7.2(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) fast-text-encoding: 1.0.6 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) tuono-fs-router-vite-plugin: 0.17.7(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) tuono-router: 0.17.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) web-streams-polyfill: 4.0.0 transitivePeerDependencies: - '@swc/helpers' @@ -7076,13 +7136,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-node@2.1.9(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)): + vite-node@2.1.9(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 1.1.2 - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) transitivePeerDependencies: - '@types/node' - less @@ -7094,7 +7154,7 @@ snapshots: - supports-color - terser - vite-plugin-dts@3.9.1(@types/node@22.13.1)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))): + vite-plugin-dts@3.9.1(@types/node@22.13.1)(rollup@4.31.0)(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)): dependencies: '@microsoft/api-extractor': 7.43.0(@types/node@22.13.1) '@rollup/pluginutils': 5.1.3(rollup@4.31.0) @@ -7105,28 +7165,28 @@ snapshots: typescript: 5.7.3 vue-tsc: 1.8.27(typescript@5.7.3) optionalDependencies: - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-externalize-deps@0.8.0(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))): + vite-plugin-externalize-deps@0.8.0(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)): dependencies: - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) - vite-tsconfig-paths@4.3.2(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))): + vite-tsconfig-paths@4.3.2(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)): dependencies: debug: 4.4.0 globrex: 0.1.2 tsconfck: 3.1.4(typescript@5.7.3) optionalDependencies: - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) transitivePeerDependencies: - supports-color - typescript - vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)): + vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1): dependencies: esbuild: 0.21.5 postcss: 8.5.1 @@ -7137,10 +7197,10 @@ snapshots: lightningcss: 1.29.1 sugarss: 4.0.1(postcss@8.5.1) - vitest@2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)): + vitest@2.1.9(@types/node@22.13.1)(happy-dom@16.8.1)(lightningcss@1.29.1)(sugarss@4.0.1): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1))) + '@vitest/mocker': 2.1.9(vite@5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -7156,8 +7216,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) - vite-node: 2.1.9(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1(postcss@8.5.1)) + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) + vite-node: 2.1.9(@types/node@22.13.1)(lightningcss@1.29.1)(sugarss@4.0.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.13.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 6ec400e4..f1101b1b 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,3 +2,4 @@ packages: - 'packages/*' - 'apps/*' - 'examples/*' + - 'e2e/fixtures/*'