diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c00ef21b..d40f7a80 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -35,6 +35,21 @@ jobs: - name: Test run: pnpm test + test-e2e: + name: Test E2E + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-and-build + + - name: Install Playwright Dependencies + run: pnpm --filter=tutorialkit-e2e exec playwright install chromium --with-deps + + - name: Test + run: pnpm test:e2e + docs: name: Docs runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 592c9c08..130572d6 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo .tmp .tmp-* +/e2e/**/test-results +/e2e/**/.astro diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..3bd3b7de --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +shell-emulator=true diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 00000000..b103c7be --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,42 @@ +# UI Tests + +> Tests for verifying TutorialKit works as expected in the browser. Tests are run against locally linked `@tutorialkit` packages. + +## Running + +- `pnpm exec playwright install chromium --with-deps` - When running the tests first time +- `pnpm test` + +## Development + +- `pnpm start` - Starts example/fixture project's development server +- `pnpm test:ui` - Start Playwright in UI mode + +## Structure + +Test cases are located in `test` directory. +Each test file has its own `chapter`, that contains `lesson`s for test cases: + +For example Navigation tests: + +``` +├── src/content/tutorial +│ └── tests +│ └──── navigation +│ ├── page-one +│ ├── page-three +│ └── page-two +└── test + └── navigation.test.ts +``` + +Or File Tree tests: + +``` +├── src/content/tutorial +│ └── tests +│ └── file-tree +│ └── lesson-and-solution +└── test + └── file-tree.test.ts +``` diff --git a/e2e/astro.config.ts b/e2e/astro.config.ts new file mode 100644 index 00000000..6814ced5 --- /dev/null +++ b/e2e/astro.config.ts @@ -0,0 +1,23 @@ +import { createRequire } from 'node:module'; +import { resolve } from 'node:path'; +import tutorialkit from '@tutorialkit/astro'; +import { defineConfig } from 'astro/config'; + +const require = createRequire(import.meta.url); +const astroDist = resolve(require.resolve('astro/package.json'), '..'); +const swapFunctionEntry = resolve(astroDist, 'dist/transitions/swap-functions.js'); + +export default defineConfig({ + devToolbar: { enabled: false }, + server: { port: 4329 }, + integrations: [tutorialkit()], + + vite: { + resolve: { + alias: { + // work-around for https://github.com/stackblitz/tutorialkit/pull/238 + 'node_modules/astro/dist/transitions/swap-functions': swapFunctionEntry, + }, + }, + }, +}); diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 00000000..7436ff52 --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,31 @@ +{ + "name": "tutorialkit-e2e", + "private": true, + "type": "module", + "scripts": { + "dev": "astro dev", + "preview": "astro build && astro preview", + "test": "playwright test", + "test:ui": "pnpm run test --ui" + }, + "devDependencies": { + "@astrojs/react": "^3.6.0", + "@iconify-json/ph": "^1.1.13", + "@iconify-json/svg-spinners": "^1.1.2", + "@playwright/test": "^1.46.0", + "@tutorialkit/astro": "workspace:*", + "@tutorialkit/components-react": "workspace:*", + "@tutorialkit/runtime": "workspace:*", + "@tutorialkit/theme": "workspace:*", + "@tutorialkit/types": "workspace:*", + "@types/node": "^22.2.0", + "@unocss/reset": "^0.59.4", + "@unocss/transformer-directives": "^0.62.0", + "astro": "^4.12.0", + "fast-glob": "^3.3.2", + "playwright": "^1.46.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "unocss": "^0.59.4" + } +} diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts new file mode 100644 index 00000000..3c09769f --- /dev/null +++ b/e2e/playwright.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + expect: { + timeout: process.env.CI ? 30_000 : 10_000, + }, + use: { + baseURL: 'http://localhost:4329', + }, + webServer: { + command: 'pnpm preview', + url: 'http://localhost:4329', + reuseExistingServer: !process.env.CI, + stdout: 'ignore', + stderr: 'pipe', + }, +}); diff --git a/e2e/public/logo.svg b/e2e/public/logo.svg new file mode 100644 index 00000000..57ad62a4 --- /dev/null +++ b/e2e/public/logo.svg @@ -0,0 +1 @@ + diff --git a/e2e/src/content/config.ts b/e2e/src/content/config.ts new file mode 100644 index 00000000..8e595c05 --- /dev/null +++ b/e2e/src/content/config.ts @@ -0,0 +1,9 @@ +import { contentSchema } from '@tutorialkit/types'; +import { defineCollection } from 'astro:content'; + +const tutorial = defineCollection({ + type: 'content', + schema: contentSchema, +}); + +export const collections = { tutorial }; diff --git a/e2e/src/content/tutorial/meta.md b/e2e/src/content/tutorial/meta.md new file mode 100644 index 00000000..29eef72c --- /dev/null +++ b/e2e/src/content/tutorial/meta.md @@ -0,0 +1,5 @@ +--- +type: tutorial +mainCommand: '' +prepareCommands: [] +--- diff --git a/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_files/example.html b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_files/example.html new file mode 100644 index 00000000..011dc537 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_files/example.html @@ -0,0 +1,8 @@ + + + Lesson file example.html title + + + Lesson file example.html content + + diff --git a/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_files/example.js b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_files/example.js new file mode 100644 index 00000000..cd356077 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_files/example.js @@ -0,0 +1 @@ +export default 'Lesson file example.js content'; diff --git a/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_solution/example.html b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_solution/example.html new file mode 100644 index 00000000..14493277 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_solution/example.html @@ -0,0 +1,8 @@ + + + Solution file example.html title + + + Solution file example.html content + + diff --git a/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_solution/example.js b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_solution/example.js new file mode 100644 index 00000000..6cf75a45 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/_solution/example.js @@ -0,0 +1 @@ +export default 'Solution file example.js content'; diff --git a/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/content.md b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/content.md new file mode 100644 index 00000000..8a53098b --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/lesson-and-solution/content.md @@ -0,0 +1,6 @@ +--- +type: lesson +title: Lesson and solution +--- + +# File Tree test - Lesson and solution diff --git a/e2e/src/content/tutorial/tests/file-tree/meta.md b/e2e/src/content/tutorial/tests/file-tree/meta.md new file mode 100644 index 00000000..0c250534 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/meta.md @@ -0,0 +1,4 @@ +--- +type: chapter +title: File Tree +--- diff --git a/e2e/src/content/tutorial/tests/file-tree/no-solution/_files/example.html b/e2e/src/content/tutorial/tests/file-tree/no-solution/_files/example.html new file mode 100644 index 00000000..011dc537 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/no-solution/_files/example.html @@ -0,0 +1,8 @@ + + + Lesson file example.html title + + + Lesson file example.html content + + diff --git a/e2e/src/content/tutorial/tests/file-tree/no-solution/_files/example.js b/e2e/src/content/tutorial/tests/file-tree/no-solution/_files/example.js new file mode 100644 index 00000000..cd356077 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/no-solution/_files/example.js @@ -0,0 +1 @@ +export default 'Lesson file example.js content'; diff --git a/e2e/src/content/tutorial/tests/file-tree/no-solution/content.md b/e2e/src/content/tutorial/tests/file-tree/no-solution/content.md new file mode 100644 index 00000000..54342155 --- /dev/null +++ b/e2e/src/content/tutorial/tests/file-tree/no-solution/content.md @@ -0,0 +1,6 @@ +--- +type: lesson +title: No solution +--- + +# File Tree test - No solution diff --git a/e2e/src/content/tutorial/tests/meta.md b/e2e/src/content/tutorial/tests/meta.md new file mode 100644 index 00000000..a9cbeaef --- /dev/null +++ b/e2e/src/content/tutorial/tests/meta.md @@ -0,0 +1,4 @@ +--- +type: part +title: Tests +--- diff --git a/e2e/src/content/tutorial/tests/navigation/meta.md b/e2e/src/content/tutorial/tests/navigation/meta.md new file mode 100644 index 00000000..4842a08d --- /dev/null +++ b/e2e/src/content/tutorial/tests/navigation/meta.md @@ -0,0 +1,10 @@ +--- +type: chapter +title: Navigation +lessons: + - page-one + - page-two + - page-three +mainCommand: '' +prepareCommands: [] +--- diff --git a/e2e/src/content/tutorial/tests/navigation/page-one/content.md b/e2e/src/content/tutorial/tests/navigation/page-one/content.md new file mode 100644 index 00000000..36d93ec8 --- /dev/null +++ b/e2e/src/content/tutorial/tests/navigation/page-one/content.md @@ -0,0 +1,6 @@ +--- +type: lesson +title: Page one +--- + +# Navigation test - Page one diff --git a/e2e/src/content/tutorial/tests/navigation/page-three/content.md b/e2e/src/content/tutorial/tests/navigation/page-three/content.md new file mode 100644 index 00000000..81e0a02e --- /dev/null +++ b/e2e/src/content/tutorial/tests/navigation/page-three/content.md @@ -0,0 +1,6 @@ +--- +type: lesson +title: Page three +--- + +# Navigation test - Page three diff --git a/e2e/src/content/tutorial/tests/navigation/page-two/content.md b/e2e/src/content/tutorial/tests/navigation/page-two/content.md new file mode 100644 index 00000000..d6d92bc5 --- /dev/null +++ b/e2e/src/content/tutorial/tests/navigation/page-two/content.md @@ -0,0 +1,6 @@ +--- +type: lesson +title: Page two +--- + +# Navigation test - Page two diff --git a/e2e/src/content/tutorial/tests/preview/meta.md b/e2e/src/content/tutorial/tests/preview/meta.md new file mode 100644 index 00000000..89205e01 --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/meta.md @@ -0,0 +1,5 @@ +--- +type: chapter +title: Preview +mainCommand: 'node ./index.mjs' +--- diff --git a/e2e/src/content/tutorial/tests/preview/multiple/content.md b/e2e/src/content/tutorial/tests/preview/multiple/content.md new file mode 100644 index 00000000..c7509b1d --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/multiple/content.md @@ -0,0 +1,9 @@ +--- +type: lesson +title: Multiple +previews: + - [8000, "First Server"] + - [8000, "Second Server", "/about.html"] +--- + +# Preview test - Multiple diff --git a/e2e/src/content/tutorial/tests/preview/single/content.md b/e2e/src/content/tutorial/tests/preview/single/content.md new file mode 100644 index 00000000..387761f4 --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/single/content.md @@ -0,0 +1,8 @@ +--- +type: lesson +title: Single +previews: + - [8000, "Node Server"] +--- + +# Preview test - Single diff --git a/test/ui/src/content/tutorial/tests/terminal/default/content.md b/e2e/src/content/tutorial/tests/terminal/default/content.md similarity index 100% rename from test/ui/src/content/tutorial/tests/terminal/default/content.md rename to e2e/src/content/tutorial/tests/terminal/default/content.md diff --git a/test/ui/src/content/tutorial/tests/terminal/meta.md b/e2e/src/content/tutorial/tests/terminal/meta.md similarity index 100% rename from test/ui/src/content/tutorial/tests/terminal/meta.md rename to e2e/src/content/tutorial/tests/terminal/meta.md diff --git a/test/ui/src/content/tutorial/tests/terminal/open-by-default/content.md b/e2e/src/content/tutorial/tests/terminal/open-by-default/content.md similarity index 100% rename from test/ui/src/content/tutorial/tests/terminal/open-by-default/content.md rename to e2e/src/content/tutorial/tests/terminal/open-by-default/content.md diff --git a/e2e/src/env.d.ts b/e2e/src/env.d.ts new file mode 100644 index 00000000..9505823a --- /dev/null +++ b/e2e/src/env.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/e2e/src/templates/default/index.mjs b/e2e/src/templates/default/index.mjs new file mode 100644 index 00000000..148d1ae2 --- /dev/null +++ b/e2e/src/templates/default/index.mjs @@ -0,0 +1,22 @@ +import http from 'node:http'; + +const server = http.createServer((req, res) => { + if (req.url === '/' || req.url === '/index.html') { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end('Index page'); + + return; + } + + if (req.url === '/about.html') { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end('About page'); + + return; + } + + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end('Not found'); +}); + +server.listen(8000); diff --git a/e2e/test/file-tree.test.ts b/e2e/test/file-tree.test.ts new file mode 100644 index 00000000..2f062049 --- /dev/null +++ b/e2e/test/file-tree.test.ts @@ -0,0 +1,59 @@ +import { test, expect } from '@playwright/test'; +import { readLessonFilesAndSolution } from './utils.js'; + +const BASE_URL = '/tests/file-tree'; + +const fixtures = readLessonFilesAndSolution('file-tree/lesson-and-solution', 'file-tree/no-solution'); + +test('user can see lesson and solution files', async ({ page }) => { + const testCase = 'lesson-and-solution'; + await page.goto(`${BASE_URL}/${testCase}`); + + await expect(page.getByRole('heading', { level: 1, name: 'File Tree test - Lesson and solution' })).toBeVisible(); + + // lesson files + for (const file of ['example.html', 'example.js']) { + await page.getByRole('button', { name: file }).click(); + await expect(page.getByRole('button', { name: file, pressed: true })).toBeVisible(); + + await expect(page.getByRole('textbox', { name: 'Editor' })).toHaveText(fixtures[testCase].files[file], { + useInnerText: true, + }); + } + + await page.getByRole('button', { name: 'Solve', disabled: false }).click(); + await expect(page.getByRole('button', { name: 'Reset' })).toBeVisible(); + + // solution files + for (const file of ['example.html', 'example.js']) { + await page.getByRole('button', { name: file }).click(); + await expect(page.getByRole('button', { name: file, pressed: true })).toBeVisible(); + + // TODO: Figure out why this is flaky + await page.waitForTimeout(1_000); + + await expect(page.getByRole('textbox', { name: 'Editor' })).toHaveText(fixtures[testCase].solution[file], { + useInnerText: true, + }); + } +}); + +test('user can see cannot click solve on lessons without solution files', async ({ page }) => { + const testCase = 'no-solution'; + await page.goto(`${BASE_URL}/${testCase}`); + + await expect(page.getByRole('heading', { level: 1, name: 'File Tree test - No solution' })).toBeVisible(); + + // lesson files + for (const file of ['example.html', 'example.js']) { + await page.getByRole('button', { name: file }).click(); + await expect(page.getByRole('button', { name: file, pressed: true })).toBeVisible(); + + await expect(page.getByRole('textbox', { name: 'Editor' })).toHaveText(fixtures[testCase].files[file], { + useInnerText: true, + }); + } + + // reset-button should be immediately visible + await expect(page.getByRole('button', { name: 'Reset' })).toBeVisible(); +}); diff --git a/e2e/test/navigation.test.ts b/e2e/test/navigation.test.ts new file mode 100644 index 00000000..bf56be55 --- /dev/null +++ b/e2e/test/navigation.test.ts @@ -0,0 +1,30 @@ +import { test, expect } from '@playwright/test'; + +const BASE_URL = '/tests/navigation/page-one'; + +test('user can navigate between lessons using nav bar links', async ({ page }) => { + await page.goto(BASE_URL); + await expect(page.getByRole('heading', { level: 1, name: 'Navigation test - Page one' })).toBeVisible(); + + // navigate forwards + await navigateToPage('Page two'); + await navigateToPage('Page three'); + + // navigate backwards + await navigateToPage('Page two'); + await navigateToPage('Page one'); + + async function navigateToPage(title: string) { + await page.getByRole('link', { name: title }).click(); + await expect(page.getByRole('heading', { level: 1, name: `Navigation test - ${title}` })).toBeVisible(); + } +}); + +test('user can navigate between lessons using breadcrumbs', async ({ page }) => { + await page.goto(BASE_URL); + + await page.getByRole('button', { name: 'Tests / Navigation / Page one' }).click({ force: true }); + await page.getByRole('region', { name: 'Navigation' }).getByRole('link', { name: 'Page three' }).click(); + + await expect(page.getByRole('heading', { level: 1, name: 'Navigation test - Page three' })).toBeVisible(); +}); diff --git a/e2e/test/preview.test.ts b/e2e/test/preview.test.ts new file mode 100644 index 00000000..7ebe4b84 --- /dev/null +++ b/e2e/test/preview.test.ts @@ -0,0 +1,26 @@ +import { test, expect } from '@playwright/test'; + +const BASE_URL = '/tests/preview'; + +test('user can see single preview tab', async ({ page }) => { + await page.goto(`${BASE_URL}/single`); + + await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Single' })).toBeVisible(); + + await expect(page.getByText('Node Server')).toBeVisible(); + + const preview = page.frameLocator('[title="Node Server"]'); + await expect(preview.getByText('Index page')).toBeVisible(); +}); + +test('user can see multiple preview tabs', async ({ page }) => { + await page.goto(`${BASE_URL}/multiple`); + + await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Multiple' })).toBeVisible(); + + await expect(page.getByText('First Server')).toBeVisible(); + await expect(page.getByText('Second Server')).toBeVisible(); + + await expect(page.frameLocator('[title="First Server"]').getByText('Index page')).toBeVisible({ timeout: 10_000 }); + await expect(page.frameLocator('[title="Second Server"]').getByText('About page')).toBeVisible({ timeout: 10_000 }); +}); diff --git a/test/ui/test/terminal.test.ts b/e2e/test/terminal.test.ts similarity index 100% rename from test/ui/test/terminal.test.ts rename to e2e/test/terminal.test.ts diff --git a/e2e/test/utils.ts b/e2e/test/utils.ts new file mode 100644 index 00000000..d874e093 --- /dev/null +++ b/e2e/test/utils.ts @@ -0,0 +1,33 @@ +import { readdirSync, readFileSync, existsSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; + +const TESTS_DIR = fileURLToPath(new URL('../src/content/tutorial/tests', import.meta.url)); + +export function readLessonFilesAndSolution( + ...lessons: string[] +): Record; solution: Record }> { + return lessons.reduce( + (all, lesson) => ({ + ...all, + [lesson.split('/')[1]]: { + files: readDirFiles(`${TESTS_DIR}/${lesson}/_files`), + solution: readDirFiles(`${TESTS_DIR}/${lesson}/_solution`), + }, + }), + {}, + ); +} + +function readDirFiles(dir: string): Record { + if (!existsSync(dir)) { + return {}; + } + + return readdirSync(dir).reduce( + (files, file) => ({ + ...files, + [file]: readFileSync(`${dir}/${file}`, 'utf8'), + }), + {}, + ); +} diff --git a/e2e/uno.config.ts b/e2e/uno.config.ts new file mode 100644 index 00000000..7018afe8 --- /dev/null +++ b/e2e/uno.config.ts @@ -0,0 +1,47 @@ +import fs from 'node:fs/promises'; +import { basename, dirname, join } from 'node:path'; +import { globSync, convertPathToPattern } from 'fast-glob'; +import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; +import { rules, shortcuts, theme } from '@tutorialkit/theme'; + +const iconPaths = globSync('./icons/languages/*.svg'); + +const customIconCollection = iconPaths.reduce( + (acc, iconPath) => { + const collectionName = basename(dirname(iconPath)); + const [iconName] = basename(iconPath).split('.'); + + acc[collectionName] ??= {}; + acc[collectionName][iconName] = async () => fs.readFile(iconPath, 'utf8'); + + return acc; + }, + {} as Record Promise>>, +); + +export default defineConfig({ + rules, + shortcuts, + theme, + content: { + inline: globSync([ + `${convertPathToPattern(join(require.resolve('@tutorialkit/components-react'), '..')).replace('\\@', '/@')}/**/*.js`, + `${convertPathToPattern(join(require.resolve('@tutorialkit/astro'), '..')).replace('\\@', '/@')}/default/**/*.astro`, + ]).map((filePath) => { + return () => fs.readFile(filePath, { encoding: 'utf8' }); + }), + }, + transformers: [transformerDirectives()], + presets: [ + presetUno({ + dark: { + dark: '[data-theme="dark"]', + }, + }), + presetIcons({ + collections: { + ...customIconCollection, + }, + }), + ], +}); diff --git a/package.json b/package.json index 049bfb39..fe8e6a9b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "scripts": { - "build": "pnpm run --stream --filter=@tutorialkit/* --filter=create-tutorial build", + "build": "pnpm run --stream --filter='@tutorialkit/*' --filter=create-tutorial build", "dev": "TUTORIALKIT_DEV=true pnpm -r --parallel --stream --filter='./packages/**' run dev", "changelog": "./scripts/changelog.mjs", "clean": "./scripts/clean.sh", @@ -16,7 +16,8 @@ "demo": "pnpm run --filter=demo.tutorialkit.dev dev", "demo:build": "pnpm run build && pnpm run --filter=demo.tutorialkit.dev build", "lint": "eslint \"{packages,docs,extensions,integration}/**/*\"", - "test": "pnpm run --stream --filter=@tutorialkit/* test --run" + "test": "pnpm run --stream --filter='@tutorialkit/*' test --run", + "test:e2e": "pnpm run --filter='./e2e' test" }, "license": "MIT", "packageManager": "pnpm@8.15.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4911772c..7282e560 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,7 +83,7 @@ importers: version: 0.59.4 astro: specifier: ^4.12.0 - version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + version: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -164,6 +164,63 @@ importers: specifier: ^0.59.4 version: 0.59.4(postcss@8.4.39)(vite@5.3.4) + e2e: + devDependencies: + '@astrojs/react': + specifier: ^3.6.0 + version: 3.6.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(vite@5.3.4) + '@iconify-json/ph': + specifier: ^1.1.13 + version: 1.1.13 + '@iconify-json/svg-spinners': + specifier: ^1.1.2 + version: 1.1.2 + '@playwright/test': + specifier: ^1.46.0 + version: 1.46.1 + '@tutorialkit/astro': + specifier: workspace:* + version: link:../packages/astro + '@tutorialkit/components-react': + specifier: workspace:* + version: link:../packages/components/react + '@tutorialkit/runtime': + specifier: workspace:* + version: link:../packages/runtime + '@tutorialkit/theme': + specifier: workspace:* + version: link:../packages/theme + '@tutorialkit/types': + specifier: workspace:* + version: link:../packages/types + '@types/node': + specifier: ^22.2.0 + version: 22.4.2 + '@unocss/reset': + specifier: ^0.59.4 + version: 0.59.4 + '@unocss/transformer-directives': + specifier: ^0.62.0 + version: 0.62.2 + astro: + specifier: ^4.12.0 + version: 4.12.2(@types/node@22.4.2)(typescript@5.5.3) + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 + playwright: + specifier: ^1.46.0 + version: 1.46.1 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + unocss: + specifier: ^0.59.4 + version: 0.59.4(postcss@8.4.39)(vite@5.3.4) + extensions/vscode: dependencies: '@volar/language-core': @@ -274,7 +331,7 @@ importers: version: 1.2.0 astro: specifier: ^4.12.0 - version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + version: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) astro-expressive-code: specifier: ^0.35.3 version: 0.35.3(astro@4.12.2) @@ -613,7 +670,7 @@ importers: version: 0.59.4 astro: specifier: ^4.12.0 - version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + version: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -795,7 +852,7 @@ packages: '@astrojs/markdown-remark': 5.1.0 '@mdx-js/mdx': 3.0.1 acorn: 8.12.0 - astro: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + astro: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) es-module-lexer: 1.5.3 estree-util-visit: 2.0.0 github-slugger: 2.0.0 @@ -2521,6 +2578,10 @@ packages: /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true + /@jridgewell/trace-mapping@0.3.25: resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} dependencies: @@ -2697,6 +2758,14 @@ packages: engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} dev: true + /@playwright/test@1.46.1: + resolution: {integrity: sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==} + engines: {node: '>=18'} + hasBin: true + dependencies: + playwright: 1.46.1 + dev: true + /@polka/url@1.0.0-next.25: resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} @@ -3243,6 +3312,12 @@ packages: dependencies: undici-types: 5.26.5 + /@types/node@22.4.2: + resolution: {integrity: sha512-nAvM3Ey230/XzxtyDcJ+VjvlzpzoHwLsF7JaDRfoI0ytO0mVheerNmM45CtA0yOILXwXXxOrcUWH3wltX+7PSw==} + dependencies: + undici-types: 6.19.8 + dev: true + /@types/normalize-package-data@2.4.4: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true @@ -3468,7 +3543,7 @@ packages: '@unocss/core': 0.59.4 '@unocss/reset': 0.59.4 '@unocss/vite': 0.59.4(vite@5.3.4) - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - rollup @@ -3503,6 +3578,10 @@ packages: /@unocss/core@0.59.4: resolution: {integrity: sha512-bBZ1sgcAtezQVZ1BST9IS3jqcsTLyqKNjiIf7FTnX3DHpfpYuMDFzSOtmkZDzBleOLO/CtcRWjT0HwTSQAmV0A==} + /@unocss/core@0.62.2: + resolution: {integrity: sha512-86jEFUJ/PSwdb1qqiEi0lWlewfKLQwiH+JAfnh8c2hLjOPVmCkb0nnsYSMh8drmtN5kpk6E06mN0IrKMO7OnvQ==} + dev: true + /@unocss/extractor-arbitrary-variants@0.59.4: resolution: {integrity: sha512-RDe4FgMGJQ+tp9GLvhPHni7Cc2O0lHBRMElVlN8LoXJAdODMICdbrEPGJlEfrc+7x/QgVFoR895KpYJh3hIgGA==} dependencies: @@ -3593,6 +3672,14 @@ packages: '@unocss/core': 0.59.4 magic-string: 0.30.10 + /@unocss/rule-utils@0.62.2: + resolution: {integrity: sha512-0za00pkDHsGZhiXBiZfOuUyT+GjCInPxMXj+QsybRU4UrjJS+d3gAteC34BqNFfDAoKQb9G5q9etXztcNHXQbg==} + engines: {node: '>=14'} + dependencies: + '@unocss/core': 0.62.2 + magic-string: 0.30.11 + dev: true + /@unocss/scope@0.59.4: resolution: {integrity: sha512-wBQJ39kw4Tfj4km7AoGvSIobPKVnRZVsgc0bema5Y0PL3g1NeVQ/LopBI2zEJWdpxGXUWxSDsXm7BZo6qVlD/A==} @@ -3623,6 +3710,14 @@ packages: '@unocss/rule-utils': 0.59.4 css-tree: 2.3.1 + /@unocss/transformer-directives@0.62.2: + resolution: {integrity: sha512-5ZGTmsXkAkFd7pHjHkGy6LGgxhh6bPbZ3jLltf98OhgBZH558y9iui6LKq3n2LpUsSZox6ey3yh1AibvakQeeg==} + dependencies: + '@unocss/core': 0.62.2 + '@unocss/rule-utils': 0.62.2 + css-tree: 2.3.1 + dev: true + /@unocss/transformer-variant-group@0.59.4: resolution: {integrity: sha512-9XLixxn1NRgP62Kj4R/NC/rpqhql5F2s6ulJ8CAMTEbd/NylVhEANluPGDVUGcLJ4cj6E02hFa8C1PLGSm7/xw==} dependencies: @@ -3643,7 +3738,7 @@ packages: chokidar: 3.6.0 fast-glob: 3.3.2 magic-string: 0.30.10 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - rollup @@ -3658,7 +3753,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.7) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - supports-color @@ -4009,7 +4104,7 @@ packages: peerDependencies: astro: ^4.0.0-beta || ^3.3.0 dependencies: - astro: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + astro: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) rehype-expressive-code: 0.35.3 /astro@4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3): @@ -4091,6 +4186,168 @@ packages: - supports-color - terser - typescript + dev: true + + /astro@4.12.2(@types/node@20.14.11)(typescript@5.5.3): + resolution: {integrity: sha512-l6OmqlL+FiuSi9x6F+EGZitteOznq1JffOil7st7cdqeMCTEIym4oagI1a6zp6QekliKWEEZWdplGhgh1k1f7Q==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + dependencies: + '@astrojs/compiler': 2.9.1 + '@astrojs/internal-helpers': 0.4.1 + '@astrojs/markdown-remark': 5.2.0 + '@astrojs/telemetry': 3.1.0 + '@babel/core': 7.24.9 + '@babel/generator': 7.24.10 + '@babel/parser': 7.24.8 + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.9 + '@types/babel__core': 7.20.5 + '@types/cookie': 0.6.0 + acorn: 8.12.1 + aria-query: 5.3.0 + axobject-query: 4.1.0 + boxen: 7.1.1 + chokidar: 3.6.0 + ci-info: 4.0.0 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 0.6.0 + cssesc: 3.0.0 + debug: 4.3.5 + deterministic-object-hash: 2.0.2 + devalue: 5.0.0 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.3 + es-module-lexer: 1.5.4 + esbuild: 0.21.5 + estree-walker: 3.0.3 + execa: 8.0.1 + fast-glob: 3.3.2 + flattie: 1.1.1 + github-slugger: 2.0.0 + gray-matter: 4.0.3 + html-escaper: 3.0.3 + http-cache-semantics: 4.1.1 + js-yaml: 4.1.0 + kleur: 4.1.5 + magic-string: 0.30.10 + mrmime: 2.0.0 + ora: 8.0.1 + p-limit: 6.1.0 + p-queue: 8.0.1 + path-to-regexp: 6.2.2 + preferred-pm: 4.0.0 + prompts: 2.4.2 + rehype: 13.0.1 + semver: 7.6.2 + shiki: 1.11.0 + string-width: 7.2.0 + strip-ansi: 7.1.0 + tsconfck: 3.1.1(typescript@5.5.3) + unist-util-visit: 5.0.0 + vfile: 6.0.2 + vite: 5.3.4(@types/node@20.14.11) + vitefu: 0.2.5(vite@5.3.4) + which-pm: 3.0.0 + yargs-parser: 21.1.1 + zod: 3.23.8 + zod-to-json-schema: 3.23.1(zod@3.23.8) + optionalDependencies: + sharp: 0.33.4 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - typescript + + /astro@4.12.2(@types/node@22.4.2)(typescript@5.5.3): + resolution: {integrity: sha512-l6OmqlL+FiuSi9x6F+EGZitteOznq1JffOil7st7cdqeMCTEIym4oagI1a6zp6QekliKWEEZWdplGhgh1k1f7Q==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + dependencies: + '@astrojs/compiler': 2.9.1 + '@astrojs/internal-helpers': 0.4.1 + '@astrojs/markdown-remark': 5.2.0 + '@astrojs/telemetry': 3.1.0 + '@babel/core': 7.24.9 + '@babel/generator': 7.24.10 + '@babel/parser': 7.24.8 + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.9 + '@types/babel__core': 7.20.5 + '@types/cookie': 0.6.0 + acorn: 8.12.1 + aria-query: 5.3.0 + axobject-query: 4.1.0 + boxen: 7.1.1 + chokidar: 3.6.0 + ci-info: 4.0.0 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 0.6.0 + cssesc: 3.0.0 + debug: 4.3.5 + deterministic-object-hash: 2.0.2 + devalue: 5.0.0 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.3 + es-module-lexer: 1.5.4 + esbuild: 0.21.5 + estree-walker: 3.0.3 + execa: 8.0.1 + fast-glob: 3.3.2 + flattie: 1.1.1 + github-slugger: 2.0.0 + gray-matter: 4.0.3 + html-escaper: 3.0.3 + http-cache-semantics: 4.1.1 + js-yaml: 4.1.0 + kleur: 4.1.5 + magic-string: 0.30.10 + mrmime: 2.0.0 + ora: 8.0.1 + p-limit: 6.1.0 + p-queue: 8.0.1 + path-to-regexp: 6.2.2 + preferred-pm: 4.0.0 + prompts: 2.4.2 + rehype: 13.0.1 + semver: 7.6.2 + shiki: 1.11.0 + string-width: 7.2.0 + strip-ansi: 7.1.0 + tsconfck: 3.1.1(typescript@5.5.3) + unist-util-visit: 5.0.0 + vfile: 6.0.2 + vite: 5.3.4(@types/node@22.4.2) + vitefu: 0.2.5(vite@5.3.4) + which-pm: 3.0.0 + yargs-parser: 21.1.1 + zod: 3.23.8 + zod-to-json-schema: 3.23.1(zod@3.23.8) + optionalDependencies: + sharp: 0.33.4 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - typescript + dev: true /astrojs-compiler-sync@1.0.0(@astrojs/compiler@2.9.1): resolution: {integrity: sha512-IM6FxpMoBxkGGdKppkFHNQIC9Wge7jspG2MIJff8DOhG41USNJLxJfxRm7wnkTKWlYK5Y1YFFNYr2vUUKkI8sw==} @@ -5386,6 +5643,14 @@ packages: universalify: 2.0.1 dev: true + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -5821,6 +6086,7 @@ packages: /immutable@4.3.6: resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} + dev: true /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -6239,6 +6505,12 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + /magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + /markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} @@ -7201,6 +7473,22 @@ packages: mlly: 1.7.1 pathe: 1.1.2 + /playwright-core@1.46.1: + resolution: {integrity: sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==} + engines: {node: '>=18'} + hasBin: true + dev: true + + /playwright@1.46.1: + resolution: {integrity: sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==} + engines: {node: '>=18'} + hasBin: true + dependencies: + playwright-core: 1.46.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /postcss-nested@6.0.1(postcss@8.4.39): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} @@ -7703,6 +7991,7 @@ packages: chokidar: 3.6.0 immutable: 4.3.6 source-map-js: 1.2.0 + dev: true /sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} @@ -8309,6 +8598,10 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + dev: true + /unherit@3.0.1: resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} @@ -8472,7 +8765,7 @@ packages: '@unocss/transformer-directives': 0.59.4 '@unocss/transformer-variant-group': 0.59.4 '@unocss/vite': 0.59.4(vite@5.3.4) - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - postcss - rollup @@ -8552,7 +8845,7 @@ packages: debug: 4.3.5 pathe: 1.1.2 picocolors: 1.0.1 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - '@types/node' - less @@ -8582,7 +8875,7 @@ packages: perfect-debounce: 1.0.0 picocolors: 1.0.1 sirv: 2.0.4 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - rollup - supports-color @@ -8599,12 +8892,47 @@ packages: debug: 4.3.5 globrex: 0.1.2 tsconfck: 3.1.0(typescript@5.5.3) - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - supports-color - typescript dev: true + /vite@5.3.4(@types/node@20.14.11): + resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.14.11 + esbuild: 0.21.5 + postcss: 8.4.39 + rollup: 4.18.1 + optionalDependencies: + fsevents: 2.3.3 + /vite@5.3.4(@types/node@20.14.11)(sass@1.77.6): resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8640,6 +8968,43 @@ packages: sass: 1.77.6 optionalDependencies: fsevents: 2.3.3 + dev: true + + /vite@5.3.4(@types/node@22.4.2): + resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 22.4.2 + esbuild: 0.21.5 + postcss: 8.4.39 + rollup: 4.18.1 + optionalDependencies: + fsevents: 2.3.3 + dev: true /vitefu@0.2.5(vite@5.3.4): resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} @@ -8649,7 +9014,7 @@ packages: vite: optional: true dependencies: - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) /vitest@1.6.0(@types/node@20.14.11): resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} @@ -8694,7 +9059,7 @@ packages: strip-literal: 2.1.0 tinybench: 2.8.0 tinypool: 0.8.4 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) vite-node: 1.6.0(@types/node@20.14.11) why-is-node-running: 2.2.2 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index de54ed4f..120900a4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,3 +4,4 @@ packages: - 'docs/*' - 'extensions/*' - 'integration' + - 'e2e'