From 9dc6929380d510f9c6316d5e56b6d1d54f25fda7 Mon Sep 17 00:00:00 2001 From: Mohammad Bagher Abiat Date: Mon, 27 Mar 2023 13:22:14 +0330 Subject: [PATCH] feat: playwright as browser provider (#3079) Co-authored-by: Vladimir Sheremet --- .github/workflows/ci.yml | 32 +++--- docs/config/index.md | 26 ++--- docs/guide/browser.md | 32 +++--- package.json | 3 +- packages/vitest/package.json | 9 +- packages/vitest/rollup.config.js | 1 + packages/vitest/src/api/setup.ts | 2 +- packages/vitest/src/defaults.ts | 6 -- packages/vitest/src/integrations/browser.ts | 14 ++- .../vitest/src/node/browser/playwright.ts | 63 +++++++++++ packages/vitest/src/node/browser/webdriver.ts | 100 +++++------------- packages/vitest/src/node/cli-api.ts | 4 +- packages/vitest/src/node/config.ts | 1 + packages/vitest/src/node/core.ts | 8 +- packages/vitest/src/node/pool.ts | 3 +- packages/vitest/src/node/pools/browser.ts | 45 ++++++++ packages/vitest/src/node/state.ts | 1 + packages/vitest/src/types/browser.ts | 21 ++-- pnpm-lock.yaml | 2 + test/browser/package.json | 4 +- test/browser/specs/runner.test.mjs | 3 +- test/browser/vitest.config.ts | 3 +- 22 files changed, 239 insertions(+), 144 deletions(-) create mode 100644 packages/vitest/src/node/browser/playwright.ts create mode 100644 packages/vitest/src/node/pools/browser.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc12538cb8ec..707d6c2ff727 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,12 +106,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - browser: [chrome, firefox, edge] + browser: [[chrome, chromium], [firefox, firefox], [edge, webkit]] timeout-minutes: 10 env: - BROWSER: ${{ matrix.browser }} + BROWSER: ${{ matrix.browser[0] }} steps: - uses: actions/checkout@v3 @@ -126,18 +126,24 @@ jobs: - name: Install run: pnpm i + - name: Install Playwright Dependencies + run: pnpx playwright install-deps + - name: Build run: pnpm run build - - name: Test Browser - run: pnpm run browser:test + - name: Test Browser (webdriverio) + run: pnpm run test:browser:webdriverio + + - name: Test Browser (playwright) + run: pnpm run test:browser:playwright + env: + BROWSER: ${{ matrix.browser[1] }} test-browser-safari: runs-on: macos-latest timeout-minutes: 10 - env: - BROWSER: safari steps: - uses: actions/checkout@v3 @@ -145,17 +151,17 @@ jobs: with: node-version: 18 - - name: Info - run: system_profiler SPSoftwareDataType - - name: Install - run: pnpm i + run: sudo pnpm i - name: Build - run: pnpm run build + run: sudo pnpm run build - name: Enable run: sudo safaridriver --enable - - name: Test Browser - run: sudo pnpm run browser:test + - name: Test Browser (webdriverio) + run: sudo BROWSER=safari pnpm run test:browser:webdriverio + + - name: Test Browser (playwright) + run: sudo BROWSER=webkit pnpm run test:browser:playwright diff --git a/docs/config/index.md b/docs/config/index.md index 72a3c92f5b25..ab9b3c54ba79 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -1001,7 +1001,7 @@ Listen to port and serve API. When set to true, the default port is 51204 - **Version:** Since Vitest 0.29.4 - **CLI:** `--browser`, `--browser=`, `--browser.name=chrome --browser.headless` -Run Vitest tests in a browser. If the browser name is not specified, Vitest will try to determine your default browser automatically. We use [WebdriverIO](https://webdriver.io/) for running tests by default, but it can be configured with [browser.provider](/config/#browser-provider) option. +Run Vitest tests in a browser. We use [WebdriverIO](https://webdriver.io/) for running tests by default, but it can be configured with [browser.provider](/config/#browser-provider) option. ::: tip NOTE Read more about testing in a real browser in the [guide page](/guide/browser). @@ -1022,11 +1022,13 @@ Run all tests inside a browser by default. Can be overriden with [`poolMatchGlob #### browser.name - **Type:** `string` -- **Default:** _tries to find default browser automatically_ - **CLI:** `--browser=safari` -Run all tests in a specific browser. If not specified, tries to find a browser automatically. +Run all tests in a specific browser. Possible options in different providers: +- `webdriverio`: `firefox`, `chrome`, `edge`, `safari` +- `playwright`: `firefox`, `webkit`, `chromium` +- custom: any string that will be passed to the provider #### browser.headless @@ -1046,21 +1048,19 @@ Configure options for Vite server that serves code in the browser. Does not affe #### browser.provider -- **Type:** `string` +- **Type:** `'webdriverio' | 'playwright' | string` - **Default:** `'webdriverio'` -- **CLI:** `--browser.provider=./custom-provider.ts` +- **CLI:** `--browser.provider=playwright` -Path to a provider that will be used when running browser tests. Provider should be exported using `default` export and have this shape: +Path to a provider that will be used when running browser tests. Vitest provides two providers which are `webdriverio` (default) and `playwright`. Custom providers should be exported using `default` export and have this shape: ```ts export interface BrowserProvider { - initialize(ctx: Vitest): Awaitable - createPool(): { - runTests: (files: string[], invalidated: string[]) => void - close: () => Awaited - } - // signals that test file stopped running, if it was opened with `id=` query - testFinished?(testId: string): Awaitable + name: string + getSupportedBrowsers(): readonly string[] + initialize(ctx: Vitest, options: { browser: string }): Awaitable + openPage(url: string): Awaitable + close(): Awaitable } ``` diff --git a/docs/guide/browser.md b/docs/guide/browser.md index 154f2e288731..fa30197a6b3a 100644 --- a/docs/guide/browser.md +++ b/docs/guide/browser.md @@ -14,7 +14,8 @@ To activate browser mode in your Vitest configuration, you can use the `--browse export default defineConfig({ test: { browser: { - enabled: true + enabled: true, + name: 'chrome', // browser name is required }, } }) @@ -22,24 +23,17 @@ export default defineConfig({ ## Browser Option Types: -The browser option in Vitest can be set to either a boolean or a string type. If set to `true`, Vitest will try to automatically find your default browser. You can also specify a browser by providing its name as a `string`. The available browser options are: -- `firefox` -- `chrome` -- `edge` -- `safari` - -Here's an example configuration setting chrome as the browser option: +The browser option in Vitest depends on the provider. Vitest will fail, if you pass `--browser` and don't specify its name in the config file. Available options: -```ts -export default defineConfig({ - test: { - browser: { - enabled: true, - name: 'chrome', - }, - } -}) -``` +- `webdriverio` (default) supports these browsers: + - `firefox` + - `chrome` + - `edge` + - `safari` +- `playwright` supports these browsers: + - `firefox` + - `webkit` + - `chromium` ## Cross-browser Testing: @@ -58,7 +52,7 @@ npx vitest --browser.name=chrome --browser.headless ``` ::: tip NOTE -When using the Safari browser option, the `safaridriver` needs to be activated by running `sudo safaridriver --enable` on your device. +When using the Safari browser option with WebdriverIO, the `safaridriver` needs to be activated by running `sudo safaridriver --enable` on your device. Additionally, when running your tests, Vitest will attempt to install some drivers for compatibility with `safaridriver`. ::: diff --git a/package.json b/package.json index cf67683b325f..e5b58dd71dbf 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "ui:build": "vite build packages/ui", "ui:dev": "vite packages/ui", "ui:test": "npm -C packages/ui run test:run", - "browser:test": "npm -C test/browser run test" + "test:browser:webdriverio": "npm -C test/browser run test:webdriverio", + "test:browser:playwright": "npm -C test/browser run test:playwright" }, "devDependencies": { "@antfu/eslint-config": "^0.34.1", diff --git a/packages/vitest/package.json b/packages/vitest/package.json index 2804e2abe9c4..9744dc575812 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -102,7 +102,10 @@ "@vitest/browser": "*", "@vitest/ui": "*", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "playwright": "*", + "safaridriver": "*", + "webdriverio": "*" }, "peerDependenciesMeta": { "@vitest/ui": { @@ -123,6 +126,9 @@ "safaridriver": { "optional": true }, + "playwright": { + "optional": true + }, "@edge-runtime/vm": { "optional": true } @@ -186,6 +192,7 @@ "natural-compare": "^1.4.0", "p-limit": "^4.0.0", "pkg-types": "^1.0.1", + "playwright": "^1.28.0", "pretty-format": "^27.5.1", "prompts": "^2.4.2", "rollup": "^2.79.1", diff --git a/packages/vitest/rollup.config.js b/packages/vitest/rollup.config.js index fb4ef9e6eaeb..6e01a51b9bfa 100644 --- a/packages/vitest/rollup.config.js +++ b/packages/vitest/rollup.config.js @@ -53,6 +53,7 @@ const external = [ 'inspector', 'webdriverio', 'safaridriver', + 'playwright', 'vite-node/source-map', 'vite-node/client', 'vite-node/server', diff --git a/packages/vitest/src/api/setup.ts b/packages/vitest/src/api/setup.ts index 57e3f7035f0d..614c13899407 100644 --- a/packages/vitest/src/api/setup.ts +++ b/packages/vitest/src/api/setup.ts @@ -36,7 +36,7 @@ export function setup(ctx: Vitest, server?: ViteDevServer) { const rpc = createBirpc( { async onDone(testId) { - await ctx.browserProvider?.testFinished?.(testId) + return ctx.state.browserTestPromises.get(testId)?.resolve(true) }, async onCollected(files) { ctx.state.collectFiles(files) diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts index b960898cc6f1..f6ed961c2e82 100644 --- a/packages/vitest/src/defaults.ts +++ b/packages/vitest/src/defaults.ts @@ -39,11 +39,6 @@ export const coverageConfigDefaults: ResolvedCoverageOptions = { extension: ['.js', '.cjs', '.mjs', '.ts', '.mts', '.cts', '.tsx', '.jsx', '.vue', '.svelte'], } -export const browserConfigDefaults = { - enabled: false, - headless: isCI, -} as const - export const fakeTimersDefaults = { loopLimit: 10_000, shouldClearNativeTimers: true, @@ -73,7 +68,6 @@ const config = { hookTimeout: 10000, teardownTimeout: 10000, isolate: true, - browser: browserConfigDefaults, watchExclude: ['**/node_modules/**', '**/dist/**'], forceRerunTriggers: [ '**/package.json/**', diff --git a/packages/vitest/src/integrations/browser.ts b/packages/vitest/src/integrations/browser.ts index 9782ec2724c6..ee0b3820a452 100644 --- a/packages/vitest/src/integrations/browser.ts +++ b/packages/vitest/src/integrations/browser.ts @@ -1,3 +1,4 @@ +import { PlaywrightBrowserProvider } from '../node/browser/playwright' import { WebdriverBrowserProvider } from '../node/browser/webdriver' import type { BrowserProviderModule, ResolvedBrowserOptions } from '../types/browser' @@ -6,8 +7,17 @@ interface Loader { } export async function getBrowserProvider(options: ResolvedBrowserOptions, loader: Loader): Promise { - if (!options.provider || options.provider === 'webdriverio') - return WebdriverBrowserProvider + switch (options.provider) { + case undefined: + case 'webdriverio': + return WebdriverBrowserProvider + + case 'playwright': + return PlaywrightBrowserProvider + + default: + break + } let customProviderModule diff --git a/packages/vitest/src/node/browser/playwright.ts b/packages/vitest/src/node/browser/playwright.ts new file mode 100644 index 000000000000..ca31c4e04dac --- /dev/null +++ b/packages/vitest/src/node/browser/playwright.ts @@ -0,0 +1,63 @@ +import type { Page } from 'playwright' +import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser' +import { ensurePackageInstalled } from '../pkg' +import type { Vitest } from '../core' + +export const playwrightBrowsers = ['firefox', 'webkit', 'chromium'] as const +export type PlaywrightBrowser = typeof playwrightBrowsers[number] + +export interface PlaywrightProviderOptions extends BrowserProviderOptions { + browser: PlaywrightBrowser +} + +export class PlaywrightBrowserProvider implements BrowserProvider { + public name = 'playwright' + + private cachedBrowser: Page | null = null + private browser!: PlaywrightBrowser + private ctx!: Vitest + + getSupportedBrowsers() { + return playwrightBrowsers + } + + async initialize(ctx: Vitest, { browser }: PlaywrightProviderOptions) { + this.ctx = ctx + this.browser = browser + + const root = this.ctx.config.root + + if (!await ensurePackageInstalled('playwright', root)) + throw new Error('Cannot find "playwright" package. Please install it manually.') + } + + async openBrowser() { + if (this.cachedBrowser) + return this.cachedBrowser + + const options = this.ctx.config.browser + + const playwright = await import('playwright') + + const playwrightInstance = await playwright[this.browser].launch({ headless: options.headless }) + this.cachedBrowser = await playwrightInstance.newPage() + + this.cachedBrowser.on('close', () => { + playwrightInstance.close() + }) + + return this.cachedBrowser + } + + async openPage(url: string) { + const browserInstance = await this.openBrowser() + await browserInstance.goto(url) + } + + async close() { + await this.cachedBrowser?.close() + // TODO: right now process can only exit with timeout, if we use browser + // needs investigating + process.exit() + } +} diff --git a/packages/vitest/src/node/browser/webdriver.ts b/packages/vitest/src/node/browser/webdriver.ts index 8e643e3cb9d1..4b4747a920f6 100644 --- a/packages/vitest/src/node/browser/webdriver.ts +++ b/packages/vitest/src/node/browser/webdriver.ts @@ -1,33 +1,32 @@ -import { promisify } from 'util' import type { Browser } from 'webdriverio' -import type { Awaitable } from '@vitest/utils' -// @ts-expect-error doesn't have types -import detectBrowser from 'x-default-browser' -import { createDefer } from '@vitest/utils' -import { relative } from 'pathe' -import type { BrowserProvider } from '../../types/browser' +import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser' import { ensurePackageInstalled } from '../pkg' import type { Vitest } from '../core' +export const webdriverBrowsers = ['firefox', 'chrome', 'edge', 'safari'] as const +export type WebdriverBrowser = typeof webdriverBrowsers[number] + +export interface WebdriverProviderOptions extends BrowserProviderOptions { + browser: WebdriverBrowser +} + export class WebdriverBrowserProvider implements BrowserProvider { + public name = 'webdriverio' + private cachedBrowser: Browser | null = null - private testDefers = new Map>() private stopSafari: () => void = () => {} - private host = '' - private browser = 'unknown' + private browser!: WebdriverBrowser private ctx!: Vitest - async initialize(ctx: Vitest) { - this.ctx = ctx - this.host = `http://${ctx.config.browser.api?.host || 'localhost'}:${ctx.browser.config.server.port}` - - const root = this.ctx.config.root - const browser = await this.getBrowserName() + getSupportedBrowsers() { + return webdriverBrowsers + } + async initialize(ctx: Vitest, { browser }: WebdriverProviderOptions) { + this.ctx = ctx this.browser = browser - if (browser === 'unknown' || !browser) - throw new Error('Cannot detect browser. Please specify it in the config file.') + const root = this.ctx.config.root if (!await ensurePackageInstalled('webdriverio', root)) throw new Error('Cannot find "webdriverio" package. Please install it manually.') @@ -36,15 +35,6 @@ export class WebdriverBrowserProvider implements BrowserProvider { throw new Error('Cannot find "safaridriver" package. Please install it manually.') } - private async resolveBrowserName(): Promise { - const browser = await promisify(detectBrowser)() - return browser.commonName - } - - async getBrowserName(): Promise { - return this.ctx.config.browser.name ?? await this.resolveBrowserName() - } - async openBrowser() { if (this.cachedBrowser) return this.cachedBrowser @@ -75,52 +65,18 @@ export class WebdriverBrowserProvider implements BrowserProvider { return this.cachedBrowser } - testFinished(id: string): Awaitable { - this.testDefers.get(id)?.resolve(true) - } - - private waitForTest(id: string) { - const defer = createDefer() - this.testDefers.set(id, defer) - return defer + async openPage(url: string) { + const browserInstance = await this.openBrowser() + await browserInstance.url(url) } - createPool() { - const runTests = async (files: string[]) => { - const paths = files.map(file => relative(this.ctx.config.root, file)) - const browserInstance = await this.openBrowser() - - const isolate = this.ctx.config.isolate - if (isolate) { - for (const path of paths) { - const url = new URL(this.host) - url.searchParams.append('path', path) - url.searchParams.set('id', path) - await browserInstance.url(url.toString()) - await this.waitForTest(path) - } - } - else { - const url = new URL(this.host) - url.searchParams.set('id', 'no-isolate') - paths.forEach(path => url.searchParams.append('path', path)) - await browserInstance.url(url.toString()) - await this.waitForTest('no-isolate') - } - } - - return { - runTests, - close: async () => { - this.testDefers.clear() - await Promise.all([ - this.stopSafari(), - this.cachedBrowser?.sessionId ? this.cachedBrowser?.deleteSession?.() : null, - ]) - // TODO: right now process can only exit with timeout, if we use browser - // needs investigating - process.exit() - }, - } + async close() { + await Promise.all([ + this.stopSafari(), + this.cachedBrowser?.sessionId ? this.cachedBrowser?.deleteSession?.() : null, + ]) + // TODO: right now process can only exit with timeout, if we use browser + // needs investigating + process.exit() } } diff --git a/packages/vitest/src/node/cli-api.ts b/packages/vitest/src/node/cli-api.ts index 0bf39e8a76b4..b22932804ed9 100644 --- a/packages/vitest/src/node/cli-api.ts +++ b/packages/vitest/src/node/cli-api.ts @@ -44,9 +44,9 @@ export async function startVitest( if (typeof options.coverage === 'boolean') options.coverage = { enabled: options.coverage } - // running "vitest --browser" + // running "vitest --browser", assumes browser name is set in the config if (typeof options.browser === 'boolean') - options.browser = { enabled: options.browser } + options.browser = { enabled: options.browser } as any // running "vitest --browser=chrome" if (typeof options.browser === 'string') diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 17ff3e747268..1f4e81f554dd 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -253,6 +253,7 @@ export function resolveConfig( resolved.exclude = resolved.typecheck.exclude } + resolved.browser ??= {} as any resolved.browser.enabled ??= false resolved.browser.headless ??= isCI diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 891eaa7d96f4..28fd156c6b25 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -150,7 +150,13 @@ export class Vitest { return this.browserProvider const Provider = await getBrowserProvider(this.config.browser, this.runner) this.browserProvider = new Provider() - await this.browserProvider.initialize(this as any) + const browser = this.config.browser.name + const supportedBrowsers = this.browserProvider.getSupportedBrowsers() + if (!browser) + throw new Error('Browser name is required. Please, set `test.browser.name` option manually.') + if (!supportedBrowsers.includes(browser)) + throw new Error(`Browser "${browser}" is not supported by the browser provider "${this.browserProvider.name}". Supported browsers: ${supportedBrowsers.join(', ')}.`) + await this.browserProvider.initialize(this, { browser }) return this.browserProvider } diff --git a/packages/vitest/src/node/pool.ts b/packages/vitest/src/node/pool.ts index 3f0a6e18d450..016bf66352e0 100644 --- a/packages/vitest/src/node/pool.ts +++ b/packages/vitest/src/node/pool.ts @@ -6,6 +6,7 @@ import type { VitestPool } from '../types' import type { Vitest } from './core' import { createChildProcessPool } from './pools/child' import { createThreadsPool } from './pools/threads' +import { createBrowserPool } from './pools/browser' export type RunWithFiles = (files: string[], invalidates?: string[]) => Promise @@ -99,7 +100,7 @@ export function createPool(ctx: Vitest): ProcessPool { return null if (ctx.browserProvider && pool === 'browser') { - pools.browser ??= ctx.browserProvider.createPool() + pools.browser ??= createBrowserPool(ctx) return pools.browser.runTests(files, invalidate) } diff --git a/packages/vitest/src/node/pools/browser.ts b/packages/vitest/src/node/pools/browser.ts new file mode 100644 index 000000000000..96782031ebd0 --- /dev/null +++ b/packages/vitest/src/node/pools/browser.ts @@ -0,0 +1,45 @@ +import { createDefer } from '@vitest/utils' +import { relative } from 'pathe' +import type { Vitest } from '../core' +import type { ProcessPool } from '../pool' + +export function createBrowserPool(ctx: Vitest): ProcessPool { + const provider = ctx.browserProvider! + const origin = `http://${ctx.config.browser.api?.host || 'localhost'}:${ctx.browser.config.server.port}` + + const waitForTest = (id: string) => { + const defer = createDefer() + ctx.state.browserTestPromises.set(id, defer) + return defer + } + + const runTests = async (files: string[]) => { + const paths = files.map(file => relative(ctx.config.root, file)) + + const isolate = ctx.config.isolate + if (isolate) { + for (const path of paths) { + const url = new URL('/', origin) + url.searchParams.append('path', path) + url.searchParams.set('id', path) + await provider.openPage(url.toString()) + await waitForTest(path) + } + } + else { + const url = new URL('/', origin) + url.searchParams.set('id', 'no-isolate') + paths.forEach(path => url.searchParams.append('path', path)) + await provider.openPage(url.toString()) + await waitForTest('no-isolate') + } + } + + return { + async close() { + ctx.state.browserTestPromises.clear() + await provider.close() + }, + runTests, + } +} diff --git a/packages/vitest/src/node/state.ts b/packages/vitest/src/node/state.ts index fb6f8f4f0890..18f5a8749b4b 100644 --- a/packages/vitest/src/node/state.ts +++ b/packages/vitest/src/node/state.ts @@ -19,6 +19,7 @@ export class StateManager { filesMap = new Map() pathsSet: Set = new Set() collectingPromise: CollectingPromise | undefined = undefined + browserTestPromises = new Map void; reject: (v: unknown) => void }>() idMap = new Map() taskFileMap = new WeakMap() errorsSet = new Set() diff --git a/packages/vitest/src/types/browser.ts b/packages/vitest/src/types/browser.ts index 88e54ed6bd08..09f0bd9f57c6 100644 --- a/packages/vitest/src/types/browser.ts +++ b/packages/vitest/src/types/browser.ts @@ -1,12 +1,17 @@ import type { Awaitable } from '@vitest/utils' import type { Vitest } from '../node' -import type { ProcessPool } from '../node/pool' import type { ApiConfig } from './config' +export interface BrowserProviderOptions { + browser: string +} + export interface BrowserProvider { - initialize(ctx: Vitest): Awaitable - createPool(): ProcessPool - testFinished?(testId: string): Awaitable + name: string + getSupportedBrowsers(): readonly string[] + initialize(ctx: Vitest, options: BrowserProviderOptions): Awaitable + openPage(url: string): Awaitable + close(): Awaitable } export interface BrowserProviderModule { @@ -23,17 +28,15 @@ export interface BrowserConfigOptions { /** * Name of the browser - * - * @default tries to find the first available browser */ - name?: 'firefox' | 'chrome' | 'edge' | 'safari' + name: string /** * browser provider * - * @default 'webdriver' + * @default 'webdriverio' */ - provider?: string + provider?: 'webdriverio' | 'playwright' | (string & {}) /** * enable headless mode diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ffd84dab8d5..fc078fcee01d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -885,6 +885,7 @@ importers: pathe: ^1.1.0 picocolors: ^1.0.0 pkg-types: ^1.0.1 + playwright: ^1.28.0 pretty-format: ^27.5.1 prompts: ^2.4.2 rollup: ^2.79.1 @@ -961,6 +962,7 @@ importers: natural-compare: 1.4.0 p-limit: 4.0.0 pkg-types: 1.0.1 + playwright: 1.28.0 pretty-format: 27.5.1 prompts: 2.4.2 rollup: 2.79.1 diff --git a/test/browser/package.json b/test/browser/package.json index 40e29bfb08d3..7ea9aa8f090b 100644 --- a/test/browser/package.json +++ b/test/browser/package.json @@ -3,7 +3,9 @@ "private": true, "module": "true", "scripts": { - "test": "node --test specs/", + "test": "pnpm run test:webdriverio && pnpm run test:playwright", + "test:webdriverio": "PROVIDER=webdriverio node --test specs/", + "test:playwright": "PROVIDER=playwright node --test specs/", "coverage": "vitest run --coverage" }, "devDependencies": { diff --git a/test/browser/specs/runner.test.mjs b/test/browser/specs/runner.test.mjs index bf076a918df1..52597aae3b26 100644 --- a/test/browser/specs/runner.test.mjs +++ b/test/browser/specs/runner.test.mjs @@ -30,7 +30,8 @@ test('logs are redirected to stdout', async () => { assert.match(stdout, /hello from console.debug/, 'prints console.debug') assert.match(stdout, /{ hello: 'from dir' }/, 'prints console.dir') assert.match(stdout, /{ hello: 'from dirxml' }/, 'prints console.dixml') - assert.match(stdout, /hello from console.trace\s+\w+/, 'prints console.trace') + // safari logs the stack files with @https://... + assert.match(stdout, /hello from console.trace\s+(\w+|@)/, 'prints console.trace') assert.match(stdout, /dom
/, 'prints dom') assert.match(stdout, /default: 1/, 'prints first default count') assert.match(stdout, /default: 2/, 'prints second default count') diff --git a/test/browser/vitest.config.ts b/test/browser/vitest.config.ts index a1378d68dfb2..2fbd47c6ab76 100644 --- a/test/browser/vitest.config.ts +++ b/test/browser/vitest.config.ts @@ -7,8 +7,9 @@ export default defineConfig({ include: ['test/**.test.{ts,js}'], browser: { enabled: true, - name: 'chrome', headless: true, + name: 'chrome', + provider: process.env.PROVIDER || 'webdriverio', }, open: false, isolate: false,