148 lines
4.4 KiB
TypeScript
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'
|