From 45b40b317402404f418fd3e504066c277c6f784e Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 17 Oct 2024 13:35:10 +0900 Subject: [PATCH 01/13] fix(browser): cleanup keybaord release state --- packages/browser/context.d.ts | 1 + packages/browser/src/client/tester/context.ts | 7 +++++++ packages/browser/src/client/tester/tester.ts | 4 ++++ packages/browser/src/node/commands/index.ts | 3 ++- packages/browser/src/node/commands/keyboard.ts | 13 +++++++++++++ packages/browser/src/node/plugins/pluginContext.ts | 1 + 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/browser/context.d.ts b/packages/browser/context.d.ts index 95f59074d7a1..d2c7b1b8fabd 100644 --- a/packages/browser/context.d.ts +++ b/packages/browser/context.d.ts @@ -59,6 +59,7 @@ export interface UserEvent { * @see {@link https://vitest.dev/guide/browser/interactivity-api.html#userevent-setup} */ setup: () => UserEvent + cleanup: () => Promise; /** * Click on an element. Uses provider's API under the hood and supports all its options. * @see {@link https://playwright.dev/docs/api/class-locator#locator-click} Playwright API diff --git a/packages/browser/src/client/tester/context.ts b/packages/browser/src/client/tester/context.ts index f498e89128a2..083351899a49 100644 --- a/packages/browser/src/client/tester/context.ts +++ b/packages/browser/src/client/tester/context.ts @@ -38,6 +38,13 @@ export function createUserEvent(__tl_user_event__?: TestingLibraryUserEvent): Us setup(options?: any) { return createUserEvent(__tl_user_event__?.setup(options)) }, + async cleanup() { + if (typeof __tl_user_event__ !== 'undefined') { + return + } + await triggerCommand('__vitest_cleanup', keyboard) + keyboard.unreleased = [] + }, click(element: Element | Locator, options: UserEventClickOptions = {}) { return convertToLocator(element).click(processClickOptions(options)) }, diff --git a/packages/browser/src/client/tester/tester.ts b/packages/browser/src/client/tester/tester.ts index 3bdc80e09fd5..7bc4f70b96fd 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -168,6 +168,10 @@ async function executeTests(method: 'run' | 'collect', files: string[]) { if (cleanupSymbol in page) { (page[cleanupSymbol] as any)() } + // TODO: symbol? + if ('__cleanup' in page) { + await (page.__cleanup as any)() + } } catch (error: any) { await client.rpc.onUnhandledError({ diff --git a/packages/browser/src/node/commands/index.ts b/packages/browser/src/node/commands/index.ts index 3568fbcc5f8d..bdbd2c7052fd 100644 --- a/packages/browser/src/node/commands/index.ts +++ b/packages/browser/src/node/commands/index.ts @@ -4,7 +4,7 @@ import { clear } from './clear' import { fill } from './fill' import { selectOptions } from './select' import { tab } from './tab' -import { keyboard } from './keyboard' +import { keyboard, keyboardCleanup } from './keyboard' import { dragAndDrop } from './dragAndDrop' import { hover } from './hover' import { upload } from './upload' @@ -34,4 +34,5 @@ export default { __vitest_selectOptions: selectOptions, __vitest_dragAndDrop: dragAndDrop, __vitest_hover: hover, + __vitest_cleanup: keyboardCleanup, } diff --git a/packages/browser/src/node/commands/keyboard.ts b/packages/browser/src/node/commands/keyboard.ts index 4341700876c3..529602cf5d82 100644 --- a/packages/browser/src/node/commands/keyboard.ts +++ b/packages/browser/src/node/commands/keyboard.ts @@ -49,6 +49,19 @@ export const keyboard: UserEventCommand<(text: string, state: KeyboardState) => } } +export const keyboardCleanup: UserEventCommand<(state: KeyboardState) => Promise> = async ( + context, + state, +) => { + const { provider, contextId } = context; + if (provider instanceof PlaywrightBrowserProvider) { + const page = provider.getPage(contextId) + for (const key of state.unreleased) { + await page.keyboard.up(key) + } + } +} + export async function keyboardImplementation( pressed: Set, provider: BrowserProvider, diff --git a/packages/browser/src/node/plugins/pluginContext.ts b/packages/browser/src/node/plugins/pluginContext.ts index f431ad399477..2160482a0a6c 100644 --- a/packages/browser/src/node/plugins/pluginContext.ts +++ b/packages/browser/src/node/plugins/pluginContext.ts @@ -85,6 +85,7 @@ export const server = { } export const commands = server.commands export const userEvent = createUserEvent(_userEventSetup) +page.__cleanup = () => userEvent.cleanup() export { page, cdp } ` } From f31dffa179769089231da734ed725fd4fba4f7f0 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 17 Oct 2024 13:49:50 +0900 Subject: [PATCH 02/13] chore: lint --- packages/browser/src/node/commands/keyboard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/browser/src/node/commands/keyboard.ts b/packages/browser/src/node/commands/keyboard.ts index 529602cf5d82..789385102f11 100644 --- a/packages/browser/src/node/commands/keyboard.ts +++ b/packages/browser/src/node/commands/keyboard.ts @@ -53,7 +53,7 @@ export const keyboardCleanup: UserEventCommand<(state: KeyboardState) => Promise context, state, ) => { - const { provider, contextId } = context; + const { provider, contextId } = context if (provider instanceof PlaywrightBrowserProvider) { const page = provider.getPage(contextId) for (const key of state.unreleased) { From 84bc8543b87dff4393f8c45072863c49a59bf067 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 17 Oct 2024 14:14:26 +0900 Subject: [PATCH 03/13] test: add test --- .../fixtures/user-event/cleanup1.test.ts | 30 +++++++++++++++++++ .../fixtures/user-event/cleanup2.test.ts | 28 +++++++++++++++++ .../fixtures/user-event/vitest.config.ts | 17 +++++++++++ 3 files changed, 75 insertions(+) create mode 100644 test/browser/fixtures/user-event/cleanup1.test.ts create mode 100644 test/browser/fixtures/user-event/cleanup2.test.ts create mode 100644 test/browser/fixtures/user-event/vitest.config.ts diff --git a/test/browser/fixtures/user-event/cleanup1.test.ts b/test/browser/fixtures/user-event/cleanup1.test.ts new file mode 100644 index 000000000000..06e075137f7d --- /dev/null +++ b/test/browser/fixtures/user-event/cleanup1.test.ts @@ -0,0 +1,30 @@ +import { expect, onTestFinished, test } from 'vitest' +import { userEvent } from '@vitest/browser/context' + +test('cleanup1', async () => { + let logs: any[] = []; + function handler(e: KeyboardEvent) { + logs.push([e.key, e.altKey]); + }; + document.addEventListener('keydown', handler) + onTestFinished(() => { + document.removeEventListener('keydown', handler); + }) + + await userEvent.keyboard('{Tab}') + // keep alt being pressed, which should be reset + // before running cleanup2.test.ts + await userEvent.keyboard("{Alt>}") + expect(logs).toMatchInlineSnapshot(` + [ + [ + "Tab", + false, + ], + [ + "Alt", + true, + ], + ] + `) +}) diff --git a/test/browser/fixtures/user-event/cleanup2.test.ts b/test/browser/fixtures/user-event/cleanup2.test.ts new file mode 100644 index 000000000000..be1950d84413 --- /dev/null +++ b/test/browser/fixtures/user-event/cleanup2.test.ts @@ -0,0 +1,28 @@ +import { expect, onTestFinished, test } from 'vitest' +import { userEvent } from '@vitest/browser/context' + +test('cleanup2', async () => { + let logs: any[] = []; + function handler(e: KeyboardEvent) { + logs.push([e.key, e.altKey]); + }; + document.addEventListener('keydown', handler) + onTestFinished(() => { + document.removeEventListener('keydown', handler); + }) + + await userEvent.keyboard('{Tab}') + await userEvent.keyboard("{Alt>}") + expect(logs).toMatchInlineSnapshot(` + [ + [ + "Tab", + false, + ], + [ + "Alt", + true, + ], + ] + `) +}) diff --git a/test/browser/fixtures/user-event/vitest.config.ts b/test/browser/fixtures/user-event/vitest.config.ts new file mode 100644 index 000000000000..c3fe79b6ac9c --- /dev/null +++ b/test/browser/fixtures/user-event/vitest.config.ts @@ -0,0 +1,17 @@ +import { fileURLToPath } from 'node:url' +import { defineConfig } from 'vitest/config' + +const provider = process.env.PROVIDER || 'playwright' +const name = + process.env.BROWSER || (provider === 'playwright' ? 'chromium' : 'chrome') + +export default defineConfig({ + cacheDir: fileURLToPath(new URL("./node_modules/.vite", import.meta.url)), + test: { + browser: { + enabled: true, + provider, + name, + }, + }, +}) From 37aa0af966f882ed02340bba9edd82f9f8fa495c Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 17 Oct 2024 14:17:05 +0900 Subject: [PATCH 04/13] chore: comment --- test/browser/fixtures/user-event/cleanup2.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/browser/fixtures/user-event/cleanup2.test.ts b/test/browser/fixtures/user-event/cleanup2.test.ts index be1950d84413..ec7d644761b6 100644 --- a/test/browser/fixtures/user-event/cleanup2.test.ts +++ b/test/browser/fixtures/user-event/cleanup2.test.ts @@ -1,6 +1,8 @@ import { expect, onTestFinished, test } from 'vitest' import { userEvent } from '@vitest/browser/context' +// exact same test as cleanup1.test.ts + test('cleanup2', async () => { let logs: any[] = []; function handler(e: KeyboardEvent) { From 4a75432ed41dc25be0a581302d1903b1bbf67b08 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 17 Oct 2024 14:19:30 +0900 Subject: [PATCH 05/13] test: add test --- test/browser/specs/runner.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/browser/specs/runner.test.ts b/test/browser/specs/runner.test.ts index 419aa61df9c4..da0a878afc07 100644 --- a/test/browser/specs/runner.test.ts +++ b/test/browser/specs/runner.test.ts @@ -137,3 +137,15 @@ error with a stack expect(stderr).toContain('Access denied to "/inaccesible/path".') }) }) + +test('user-event', async () => { + const { ctx } = await runBrowserTests({ + root: './fixtures/user-event', + }) + expect(Object.fromEntries(ctx.state.getFiles().map(f => [f.name, f.result.state]))).toMatchInlineSnapshot(` + { + "cleanup1.test.ts": "pass", + "cleanup2.test.ts": "pass", + } + `) +}) From 423b2ecf2644eddf51bbe1bd99b81335ce4e8731 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 17 Oct 2024 14:36:38 +0900 Subject: [PATCH 06/13] refactor: use symbol --- packages/browser/src/client/tester/tester.ts | 6 +++--- packages/browser/src/node/plugins/pluginContext.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/browser/src/client/tester/tester.ts b/packages/browser/src/client/tester/tester.ts index 7bc4f70b96fd..539bc76ad35b 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -11,6 +11,7 @@ import { VitestBrowserClientMocker } from './mocker' import { setupExpectDom } from './expect-element' const cleanupSymbol = Symbol.for('vitest:component-cleanup') +const userEventCleanupSymbol = Symbol.for('vitest:user-event-cleanup') const url = new URL(location.href) const reloadStart = url.searchParams.get('__reloadStart') @@ -168,9 +169,8 @@ async function executeTests(method: 'run' | 'collect', files: string[]) { if (cleanupSymbol in page) { (page[cleanupSymbol] as any)() } - // TODO: symbol? - if ('__cleanup' in page) { - await (page.__cleanup as any)() + if (userEventCleanupSymbol in page) { + await (page[userEventCleanupSymbol] as any)() } } catch (error: any) { diff --git a/packages/browser/src/node/plugins/pluginContext.ts b/packages/browser/src/node/plugins/pluginContext.ts index 2160482a0a6c..ccdbcd6d4903 100644 --- a/packages/browser/src/node/plugins/pluginContext.ts +++ b/packages/browser/src/node/plugins/pluginContext.ts @@ -85,8 +85,8 @@ export const server = { } export const commands = server.commands export const userEvent = createUserEvent(_userEventSetup) -page.__cleanup = () => userEvent.cleanup() export { page, cdp } +page[Symbol.for('vitest:user-event-cleanup')] = () => userEvent.cleanup() ` } From 616ca652192face0e51a96f0b05f31bc8418ec6d Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 18 Oct 2024 10:48:43 +0900 Subject: [PATCH 07/13] chore: cleanup in onAfterRunTask --- packages/browser/src/client/tester/runner.ts | 3 ++- packages/browser/src/client/tester/tester.ts | 4 ---- packages/browser/src/node/plugins/pluginContext.ts | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index 83bf799cf1b7..370046c3acb4 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -4,7 +4,7 @@ import type { VitestExecutor } from 'vitest/execute' import { NodeBenchmarkRunner, VitestTestRunner } from 'vitest/runners' import { loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker } from 'vitest/browser' import { TraceMap, originalPositionFor } from 'vitest/utils' -import { page } from '@vitest/browser/context' +import { page, userEvent } from '@vitest/browser/context' import { globalChannel } from '@vitest/browser/client' import { executor } from '../utils' import { VitestBrowserSnapshotEnvironment } from './snapshot' @@ -41,6 +41,7 @@ export function createBrowserRunner( } onAfterRunTask = async (task: Task) => { + await userEvent.cleanup() await super.onAfterRunTask?.(task) if (this.config.bail && task.result?.state === 'fail') { diff --git a/packages/browser/src/client/tester/tester.ts b/packages/browser/src/client/tester/tester.ts index 539bc76ad35b..3bdc80e09fd5 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -11,7 +11,6 @@ import { VitestBrowserClientMocker } from './mocker' import { setupExpectDom } from './expect-element' const cleanupSymbol = Symbol.for('vitest:component-cleanup') -const userEventCleanupSymbol = Symbol.for('vitest:user-event-cleanup') const url = new URL(location.href) const reloadStart = url.searchParams.get('__reloadStart') @@ -169,9 +168,6 @@ async function executeTests(method: 'run' | 'collect', files: string[]) { if (cleanupSymbol in page) { (page[cleanupSymbol] as any)() } - if (userEventCleanupSymbol in page) { - await (page[userEventCleanupSymbol] as any)() - } } catch (error: any) { await client.rpc.onUnhandledError({ diff --git a/packages/browser/src/node/plugins/pluginContext.ts b/packages/browser/src/node/plugins/pluginContext.ts index ccdbcd6d4903..f431ad399477 100644 --- a/packages/browser/src/node/plugins/pluginContext.ts +++ b/packages/browser/src/node/plugins/pluginContext.ts @@ -86,7 +86,6 @@ export const server = { export const commands = server.commands export const userEvent = createUserEvent(_userEventSetup) export { page, cdp } -page[Symbol.for('vitest:user-event-cleanup')] = () => userEvent.cleanup() ` } From 231877d036a49f1799077449ae1c9fa9e618a402 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 18 Oct 2024 10:53:11 +0900 Subject: [PATCH 08/13] test: per-test cleanup --- .../fixtures/user-event/cleanup1.test.ts | 29 +++++++++++++++++-- .../fixtures/user-event/cleanup2.test.ts | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/test/browser/fixtures/user-event/cleanup1.test.ts b/test/browser/fixtures/user-event/cleanup1.test.ts index 06e075137f7d..9b6ef3996ed6 100644 --- a/test/browser/fixtures/user-event/cleanup1.test.ts +++ b/test/browser/fixtures/user-event/cleanup1.test.ts @@ -12,8 +12,33 @@ test('cleanup1', async () => { }) await userEvent.keyboard('{Tab}') - // keep alt being pressed, which should be reset - // before running cleanup2.test.ts + await userEvent.keyboard("{Alt>}") + expect(logs).toMatchInlineSnapshot(` + [ + [ + "Tab", + false, + ], + [ + "Alt", + true, + ], + ] + `) +}) + +// test per-test cleanup +test('cleanup1.2', async () => { + let logs: any[] = []; + function handler(e: KeyboardEvent) { + logs.push([e.key, e.altKey]); + }; + document.addEventListener('keydown', handler) + onTestFinished(() => { + document.removeEventListener('keydown', handler); + }) + + await userEvent.keyboard('{Tab}') await userEvent.keyboard("{Alt>}") expect(logs).toMatchInlineSnapshot(` [ diff --git a/test/browser/fixtures/user-event/cleanup2.test.ts b/test/browser/fixtures/user-event/cleanup2.test.ts index ec7d644761b6..75e66d124050 100644 --- a/test/browser/fixtures/user-event/cleanup2.test.ts +++ b/test/browser/fixtures/user-event/cleanup2.test.ts @@ -1,7 +1,7 @@ import { expect, onTestFinished, test } from 'vitest' import { userEvent } from '@vitest/browser/context' -// exact same test as cleanup1.test.ts +// test per-test-file cleanup just in case test('cleanup2', async () => { let logs: any[] = []; From 983ea440ee9c59c0b56b892febed3f6fd770f114 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 18 Oct 2024 11:25:27 +0900 Subject: [PATCH 09/13] fix: fix preview mode cleanup --- packages/browser/src/client/tester/context.ts | 4 +++- packages/browser/src/node/plugins/pluginContext.ts | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/browser/src/client/tester/context.ts b/packages/browser/src/client/tester/context.ts index 083351899a49..0d3b5e3b8f15 100644 --- a/packages/browser/src/client/tester/context.ts +++ b/packages/browser/src/client/tester/context.ts @@ -29,7 +29,8 @@ function triggerCommand(command: string, ...args: any[]) { return rpc().triggerCommand(contextId, command, filepath(), args) } -export function createUserEvent(__tl_user_event__?: TestingLibraryUserEvent): UserEvent { +export function createUserEvent(__tl_user_event_base__?: TestingLibraryUserEvent): UserEvent { + let __tl_user_event__ = __tl_user_event_base__?.setup({}) const keyboard = { unreleased: [] as string[], } @@ -40,6 +41,7 @@ export function createUserEvent(__tl_user_event__?: TestingLibraryUserEvent): Us }, async cleanup() { if (typeof __tl_user_event__ !== 'undefined') { + __tl_user_event__ = __tl_user_event_base__?.setup({}) return } await triggerCommand('__vitest_cleanup', keyboard) diff --git a/packages/browser/src/node/plugins/pluginContext.ts b/packages/browser/src/node/plugins/pluginContext.ts index f431ad399477..1c31f1d13fe9 100644 --- a/packages/browser/src/node/plugins/pluginContext.ts +++ b/packages/browser/src/node/plugins/pluginContext.ts @@ -97,7 +97,8 @@ async function getUserEventImport(provider: BrowserProvider, resolve: (id: strin if (!resolved) { throw new Error(`Failed to resolve user-event package from ${__dirname}`) } - return `import { userEvent as __vitest_user_event__ } from '${slash( - `/@fs/${resolved.id}`, - )}'\nconst _userEventSetup = __vitest_user_event__.setup()\n` + return `\ +import { userEvent as __vitest_user_event__ } from '${slash(`/@fs/${resolved.id}`)}' +const _userEventSetup = __vitest_user_event__ +` } From cf0ce9125576d3e6a6c649eec66e304332f2a899 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 18 Oct 2024 11:40:43 +0900 Subject: [PATCH 10/13] fix: fix webdriverio/firefox --- packages/browser/src/node/commands/keyboard.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/browser/src/node/commands/keyboard.ts b/packages/browser/src/node/commands/keyboard.ts index 789385102f11..b3a259b907a8 100644 --- a/packages/browser/src/node/commands/keyboard.ts +++ b/packages/browser/src/node/commands/keyboard.ts @@ -60,6 +60,13 @@ export const keyboardCleanup: UserEventCommand<(state: KeyboardState) => Promise await page.keyboard.up(key) } } + else if (provider instanceof WebdriverBrowserProvider) { + const keyboard = provider.browser!.action('key') + for (const key of state.unreleased) { + keyboard.up(key) + } + await keyboard.perform() + } } export async function keyboardImplementation( From 594174340471b992d14f48e6be54cc7508104d01 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 18 Oct 2024 18:05:56 +0900 Subject: [PATCH 11/13] fix: fresh setup --- packages/browser/src/client/tester/context.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/browser/src/client/tester/context.ts b/packages/browser/src/client/tester/context.ts index 0d3b5e3b8f15..613740bc9fef 100644 --- a/packages/browser/src/client/tester/context.ts +++ b/packages/browser/src/client/tester/context.ts @@ -1,6 +1,6 @@ import type { RunnerTask } from 'vitest' import type { BrowserRPC } from '@vitest/browser/client' -import type { UserEvent as TestingLibraryUserEvent } from '@testing-library/user-event' +import type { Options as TestingLibraryOptions, UserEvent as TestingLibraryUserEvent } from '@testing-library/user-event' import type { BrowserPage, Locator, @@ -29,19 +29,19 @@ function triggerCommand(command: string, ...args: any[]) { return rpc().triggerCommand(contextId, command, filepath(), args) } -export function createUserEvent(__tl_user_event_base__?: TestingLibraryUserEvent): UserEvent { - let __tl_user_event__ = __tl_user_event_base__?.setup({}) +export function createUserEvent(__tl_user_event_base__?: TestingLibraryUserEvent, options?: TestingLibraryOptions): UserEvent { + let __tl_user_event__ = __tl_user_event_base__?.setup(options ?? {}) const keyboard = { unreleased: [] as string[], } return { setup(options?: any) { - return createUserEvent(__tl_user_event__?.setup(options)) + return createUserEvent(__tl_user_event_base__, options) }, async cleanup() { - if (typeof __tl_user_event__ !== 'undefined') { - __tl_user_event__ = __tl_user_event_base__?.setup({}) + if (typeof __tl_user_event_base__ !== 'undefined') { + __tl_user_event__ = __tl_user_event_base__?.setup(options ?? {}) return } await triggerCommand('__vitest_cleanup', keyboard) From f97ee5c52508bfb24281cb2fd1a37cf5e762d20a Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 18 Oct 2024 18:10:35 +0900 Subject: [PATCH 12/13] fix: error for unsupported provider --- packages/browser/src/node/commands/keyboard.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/browser/src/node/commands/keyboard.ts b/packages/browser/src/node/commands/keyboard.ts index b3a259b907a8..852a2fd2ca51 100644 --- a/packages/browser/src/node/commands/keyboard.ts +++ b/packages/browser/src/node/commands/keyboard.ts @@ -67,6 +67,9 @@ export const keyboardCleanup: UserEventCommand<(state: KeyboardState) => Promise } await keyboard.perform() } + else { + throw new TypeError(`Provider "${context.provider.name}" does not support keyboard api`) + } } export async function keyboardImplementation( From b23c8ae195d1c10220a6287dd914d41657e947ff Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 21 Oct 2024 08:38:29 +0900 Subject: [PATCH 13/13] docs: jsdoc and context.md --- docs/guide/browser/context.md | 1 + packages/browser/context.d.ts | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/guide/browser/context.md b/docs/guide/browser/context.md index 5780534c0288..744bb37ec597 100644 --- a/docs/guide/browser/context.md +++ b/docs/guide/browser/context.md @@ -20,6 +20,7 @@ The `userEvent` API is explained in detail at [Interactivity API](/guide/browser */ export const userEvent: { setup: () => UserEvent + cleanup: () => Promise click: (element: Element, options?: UserEventClickOptions) => Promise dblClick: (element: Element, options?: UserEventDoubleClickOptions) => Promise tripleClick: (element: Element, options?: UserEventTripleClickOptions) => Promise diff --git a/packages/browser/context.d.ts b/packages/browser/context.d.ts index d2c7b1b8fabd..c332b1df9de9 100644 --- a/packages/browser/context.d.ts +++ b/packages/browser/context.d.ts @@ -59,7 +59,12 @@ export interface UserEvent { * @see {@link https://vitest.dev/guide/browser/interactivity-api.html#userevent-setup} */ setup: () => UserEvent - cleanup: () => Promise; + /** + * Cleans up the user event instance, releasing any resources or state it holds, + * such as keyboard press state. For the default `userEvent` instance, this method + * is automatically called after each test case. + */ + cleanup: () => Promise /** * Click on an element. Uses provider's API under the hood and supports all its options. * @see {@link https://playwright.dev/docs/api/class-locator#locator-click} Playwright API