diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a14222b..cc7a1f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,11 +35,15 @@ jobs: - name: Typecheck run: pnpm typecheck + - name: Install Playwright Dependencies + run: pnpm exec playwright install chromium --with-deps + - name: Test run: pnpm test publish-preview: runs-on: ubuntu-latest + if: ${{ false }} # TODO: Set up preview deployments steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index da592f8..c3bac2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .DS_Store dist +__screenshots__ \ No newline at end of file diff --git a/README.md b/README.md index 7e1f53d..036ead6 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,108 @@ -# @webcontainer/playwright +# @webcontainer/test [![Version][version-badge]][npm-url] -> Playwright utilities for testing applications in WebContainers +> Utilities for testing applications in WebContainers -[Installation](#installation) | [API](#api) +[Installation](#installation) | [Configuration](#configuration) | [API](#api) --- -Test your applications and packages inside WebContainers using Playwright. +Test your applications and packages inside WebContainers. ## Installation +Add `@webcontainer/test` to your development dependencies. + ```sh -$ npm install --save-dev @webcontainer/playwright +$ npm install --save-dev @webcontainer/test ``` -`@playwright/test` is required as peer dependency: +Vitest is also required as peer dependency. ```sh -$ npm install --save-dev @playwright/test +$ npm install --save-dev vitest @vitest/browser ``` -## API - -### Fixtures +## Configuration -WebContainer utilities are defined as [Playwright fixtures](https://playwright.dev/docs/test-fixtures). You can import pre-defined `test()`, or import each fixture manually and extend your own `test` with each fixture. - -```ts -// Pre-defined test() -import { test } from "@webcontainer/playwright"; -``` +Add `vitestWebcontainers` plugin in your Vitest config and enable browser mode: ```ts -// Manual import of each fixture -import { - Editor, - Preview, - Terminal, - WebContainer, -} from "@webcontainer/playwright"; -import { test as base } from "@playwright/test"; - -const test = base.extend<{ - editor: Editor; - preview: Preview; - terminal: Terminal; - webcontainer: WebContainer; -}>({ - editor: async ({ page }, use) => { - use(new Editor(page)); - }, - preview: async ({ page }, use) => { - use(new Preview(page)); - }, - terminal: async ({ page }, use) => { - use(new Terminal(page)); - }, - webcontainer: async ({ page }, use) => { - use(new WebContainer(page)); +import { defineConfig } from "vitest/config"; +import { vitestWebcontainers } from "@webcontainer/test/plugin"; + +export default defineConfig({ + plugins: [vitestWebcontainers()], + test: { + browser: { + enabled: true, + provider: "playwright", + instances: [{ browser: "chromium" }], + }, }, }); - -export { test }; ``` -You can access each fixture in your test cases: +## API + +Webcontainer utilities are exposed as [test fixtures](https://vitest.dev/guide/test-context.html#test-extend). ```ts -import { test } from "@webcontainer/playwright"; // or your own `test` setup +import { test } from "@webcontainer/test"; -test("user can open Vite TypeScript starter", async ({ - page, - editor, +test("run development server inside webcontainer", async ({ + webcontainer, preview, - terminal, }) => { - await page.goto("/"); + await webcontainer.mount("path/to/project"); - await editor.getByFile("package.json", /"vite": "^6.0.11"/); - await editor.getByFile("src/main.ts", /

Hello Vite<\/h1>/); + await webcontainer.runCommand("npm", ["install"]); + webcontainer.runCommand("npm", ["run", "dev"]); - await terminal.getByText("VITE v6.0.11 ready"); - - await preview.getByRole("heading", { level: 1, name: "Hello Vite" }); + await preview.getByRole("heading", { level: 1, name: "Hello Vite!" }); }); ``` -#### Editor +#### `preview` -##### `getByFile` +##### `getByRole` -Get file by its name and content. +Vitest's [`getByRole`](https://vitest.dev/guide/browser/locators.html#getbyrole) that's scoped to the preview window. ```ts -async function getByFile(filename: string, content: RegExp | string): Locator; +await preview.getByRole("heading", { level: 1, name: "Hello Vite!" }); ``` -#### Preview +##### `getByText` -##### `getByRole` +Vitest's [`getByText`](https://vitest.dev/guide/browser/locators.html#getbytext) that's scoped to the preview window. -Playwright's [`getByRole`](https://playwright.dev/docs/api/class-framelocator#frame-locator-get-by-role) that's scoped to the preview `