From b629299662d99f5f1f96d78a7a057caa5245fe71 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 22 Oct 2024 11:07:57 +0900 Subject: [PATCH 1/2] test: add repro --- .../fixtures/user-event/cleanup-retry.test.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 test/browser/fixtures/user-event/cleanup-retry.test.ts diff --git a/test/browser/fixtures/user-event/cleanup-retry.test.ts b/test/browser/fixtures/user-event/cleanup-retry.test.ts new file mode 100644 index 000000000000..a2e68d579e72 --- /dev/null +++ b/test/browser/fixtures/user-event/cleanup-retry.test.ts @@ -0,0 +1,31 @@ +import { expect, onTestFinished, test } from 'vitest' +import { userEvent } from '@vitest/browser/context' + +test('cleanup retry', { retry: 1 }, async (ctx) => { + 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>}") + if (ctx.task.result.retryCount === 0) { + throw new Error("test retry") + } + expect(logs).toEqual( + [ + [ + "Tab", + false, + ], + [ + "Alt", + true, + ], + ] + ) +}) From ddaa575f3b53c0c162d86871da00eb0c67baffeb Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 22 Oct 2024 14:00:37 +0900 Subject: [PATCH 2/2] fix: cleanup before try and after tester --- packages/browser/src/client/tester/runner.ts | 6 +++++- packages/browser/src/client/tester/tester.ts | 5 ++++- test/browser/specs/runner.test.ts | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index dea0f2645a24..43678f61d83b 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -40,8 +40,12 @@ export function createBrowserRunner( this.config = options.config } - onAfterRunTask = async (task: Task) => { + onBeforeTryTask: VitestRunner['onBeforeTryTask'] = async (...args) => { await userEvent.cleanup() + await super.onBeforeTryTask?.(...args) + } + + onAfterRunTask = async (task: Task) => { 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 37a582ce887d..0114aaee0207 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -1,5 +1,5 @@ import { SpyModule, collectTests, setupCommonEnv, startCoverageInsideWorker, startTests, stopCoverageInsideWorker } from 'vitest/browser' -import { page } from '@vitest/browser/context' +import { page, userEvent } from '@vitest/browser/context' import type { IframeMockEvent, IframeMockInvalidateEvent, IframeUnmockEvent } from '@vitest/browser/client' import { channel, client, onCancel, waitForChannel } from '@vitest/browser/client' import { executor, getBrowserState, getConfig, getWorkerState } from '../utils' @@ -168,6 +168,9 @@ async function executeTests(method: 'run' | 'collect', files: string[]) { if (cleanupSymbol in page) { (page[cleanupSymbol] as any)() } + // need to cleanup for each tester + // since playwright keybaord API is stateful on page instance level + await userEvent.cleanup() } catch (error: any) { await client.rpc.onUnhandledError({ diff --git a/test/browser/specs/runner.test.ts b/test/browser/specs/runner.test.ts index da0a878afc07..0347d9be2d42 100644 --- a/test/browser/specs/runner.test.ts +++ b/test/browser/specs/runner.test.ts @@ -144,6 +144,7 @@ test('user-event', async () => { }) expect(Object.fromEntries(ctx.state.getFiles().map(f => [f.name, f.result.state]))).toMatchInlineSnapshot(` { + "cleanup-retry.test.ts": "pass", "cleanup1.test.ts": "pass", "cleanup2.test.ts": "pass", }