Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions apps/web/test/browserSetup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { beforeEach } from "vite-plus/test";
import { commands } from "vite-plus/test/browser";

declare module "vite-plus/test/browser" {
interface BrowserCommands {
/** Defined in vite.config.ts. Moves Playwright's mouse off the page. */
resetPointer: () => Promise<void>;
}
}

// Playwright's mouse outlives each test and each file, so whatever the next test mounts
// under its last position starts hovered. Registered here rather than in render() so tests
// that mount without it are covered too. Before each test, not after: a timed-out test keeps
// running and can move the mouse after its own afterEach.
beforeEach(async () => {
await commands.resetPointer();
});
13 changes: 1 addition & 12 deletions apps/web/test/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,12 @@ import {
import { act as reactAct, createContext, use, type ReactNode } from "react";
import { createRoot } from "react-dom/client";
import { vi } from "vite-plus/test";
import { commands, page, utils, type Locator, type LocatorSelectors } from "vite-plus/test/browser";
import { page, utils, type Locator, type LocatorSelectors } from "vite-plus/test/browser";

declare global {
var IS_REACT_ACT_ENVIRONMENT: boolean | undefined;
}

declare module "vite-plus/test/browser" {
interface BrowserCommands {
/** Defined in vite.config.ts. Moves Playwright's mouse off the page. */
resetPointer: () => Promise<void>;
}
}

// React warns about every update outside act() while this flag is on, and a real
// browser drives updates from userEvent, timers and network that act() cannot wrap.
// So it is on only while act() runs, and nested calls restore the outer value.
Expand Down Expand Up @@ -104,10 +97,6 @@ export async function render(
await unmount();
} finally {
container.remove();
// The real mouse outlives the test, and whatever the next test mounts under it
// starts hovered. Parking it here keeps render() itself free of awaits before
// the first mount, which tests rely on.
await commands.resetPointer();
}
},
};
Expand Down
3 changes: 2 additions & 1 deletion apps/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const browserTestProject = {
include: ["src/**/*.browser.test.{ts,tsx}"],
hookTimeout: 15_000,
testTimeout: 15_000,
setupFiles: ["./test/browserSetup.ts"],
api: { port: browserTestApiPort, strictPort: false },
browser: {
enabled: true,
Expand All @@ -110,7 +111,7 @@ const browserTestProject = {
screenshotFailures: false,
commands: {
// Playwright's mouse outlives each test, so whatever mounts under its last
// position starts hovered. test/render.tsx parks it off the page after each test.
// position starts hovered. test/browserSetup.ts parks it off the page before each test.
resetPointer: async ({ page }) => {
await page.mouse.move(-1, -1);
},
Expand Down
Loading