Files
Imhotep/packages/imhotep-playwright/src/fixture.ts
T

148 lines
4.4 KiB
TypeScript

/**
* Playwright test fixtures for Imhotep.
*
* Provides a native Playwright fixture that injects an Imhotep page
* wrapper into every test, enabling fluent relational assertions
* directly within Playwright test suites.
*/
import { test as baseTest } from '@playwright/test'
import type { TestFixture, WorkerFixture, Fixtures, PlaywrightTestArgs, PlaywrightWorkerArgs } from '@playwright/test'
import { ImhotepPage, ImhotepPageOptions } from './page.js'
import { ImhotepRuntime, createRuntime } from './runtime.js'
import { EnvironmentCase } from './environment.js'
/**
* Extended Playwright test type with Imhotep fixtures.
*
* Usage:
*
* ```js
* import { test } from 'imhotep-playwright'
*
* test('product page layout', async ({ page, imhotepPage }) => {
* await page.goto('/products/123')
* // Use imhotepPage for assertions...
* })
* ```
*/
export interface ImhotepFixtures {
/**
* The Imhotep runtime for the current worker process.
*
* One runtime is created per worker and manages pooled browser
* contexts and pages.
*/
imhotepRuntime: ImhotepRuntime
/**
* The Imhotep page wrapper borrowed for the current test.
*
* This is automatically borrowed from the worker runtime and
* returned after the test completes.
*/
imhotepPage: ImhotepPage
/**
* Optional environment case applied before the test begins.
*
* If provided, the fixture will configure the page viewport,
* color scheme, pointer type, and reduced-motion preference.
*/
imhotepEnvironment: EnvironmentCase | undefined
/**
* Options passed to the Imhotep runtime and page wrappers.
*/
imhotepOptions: ImhotepPageOptions
}
/** Internal test-scoped fixtures for type safety. */
interface ImhotepTestFixtures {
imhotepPage: ImhotepPage
imhotepEnvironment: EnvironmentCase | undefined
}
/** Internal worker-scoped fixtures for type safety. */
interface ImhotepWorkerFixtures {
imhotepRuntime: ImhotepRuntime
imhotepOptions: ImhotepPageOptions
}
/**
* Default environment case used when none is explicitly provided.
*/
export const defaultEnvironment: EnvironmentCase = {
viewport: { width: 1280, height: 720 },
colorScheme: 'no-preference',
reducedMotion: 'no-preference',
}
// ---------------------------------------------------------------------------
// Individual fixture definitions with explicit types.
// ---------------------------------------------------------------------------
const imhotepOptionsFixture: WorkerFixture<ImhotepPageOptions, ImhotepWorkerFixtures & PlaywrightWorkerArgs> = async (
{},
use
) => {
await use({ injectRuntime: true })
}
const imhotepEnvironmentFixture: TestFixture<EnvironmentCase | undefined, ImhotepTestFixtures & ImhotepWorkerFixtures & PlaywrightTestArgs & PlaywrightWorkerArgs> = async (
{},
use
) => {
await use(defaultEnvironment)
}
const imhotepRuntimeFixture: WorkerFixture<ImhotepRuntime, ImhotepWorkerFixtures & PlaywrightWorkerArgs> = async (
{ browser, imhotepOptions },
use
) => {
const runtime = await createRuntime(browser, { pageOptions: imhotepOptions })
await use(runtime)
await runtime.shutdown()
}
const imhotepPageFixture: TestFixture<ImhotepPage, ImhotepTestFixtures & ImhotepWorkerFixtures & PlaywrightTestArgs & PlaywrightWorkerArgs> = async (
{ imhotepRuntime, imhotepEnvironment },
use
) => {
const page = await imhotepRuntime.createPage()
if (imhotepEnvironment) {
await page.applyEnvironment(imhotepEnvironment)
}
await use(page)
await imhotepRuntime.releasePage(page)
}
/**
* The base Imhotep fixtures object.
*
* Extend this with `test.extend()` if you need to add custom fixtures
* or override defaults for a specific test file.
*/
export const imhotepFixtures: Fixtures<ImhotepTestFixtures, ImhotepWorkerFixtures, PlaywrightTestArgs, PlaywrightWorkerArgs> = {
imhotepOptions: [imhotepOptionsFixture, { scope: 'worker', option: true }],
imhotepEnvironment: [imhotepEnvironmentFixture, { option: true }],
imhotepRuntime: [imhotepRuntimeFixture, { scope: 'worker' }],
imhotepPage: [imhotepPageFixture, { scope: 'test' }],
}
/**
* Pre-extended Playwright test object with Imhotep fixtures.
*
* Import this instead of `@playwright/test` to get Imhotep support
* out of the box.
*/
export const test = baseTest.extend<ImhotepTestFixtures, ImhotepWorkerFixtures>(imhotepFixtures)
/**
* Re-export `expect` from Playwright so that test files only need
* one import.
*/
export { expect } from '@playwright/test'