UNPKG

@serenity-js/playwright-test

Version:

Serenity/JS test runner adapter for Playwright Test, combining Playwright's developer experience with the advanced reporting and automation capabilities of Serenity/JS

351 lines 15.6 kB
import type { Expect, Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestInfo, TestType } from '@playwright/test'; import type { DiffFormatter } from '@serenity-js/core'; import { PlaywrightTestSceneIdFactory } from '../reporter/PlaywrightTestSceneIdFactory'; import type { SerenityFixtures, SerenityWorkerFixtures } from './serenity-fixtures'; import { WorkerEventStreamWriter } from './WorkerEventStreamWriter'; interface SerenityInternalFixtures { configureScenarioInternal: void; } interface SerenityInternalWorkerFixtures { configureWorkerInternal: void; sceneIdFactoryInternal: PlaywrightTestSceneIdFactory; diffFormatterInternal: DiffFormatter; eventStreamWriterInternal: WorkerEventStreamWriter; } export declare const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, SerenityWorkerFixtures & SerenityInternalWorkerFixtures, PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>; /** * Serenity/JS BDD-style test API created by [`useBase`](https://serenity-js.org/api/playwright-test/function/useBase/). */ export type TestApi<TestArgs extends Record<string, any>, WorkerArgs extends Record<string, any>> = Pick<TestType<TestArgs, WorkerArgs>, 'describe' | 'beforeAll' | 'beforeEach' | 'afterEach' | 'afterAll' | 'expect'> & { /** * Creates a Serenity/JS BDD-style test API around the default Playwright [base test](https://playwright.dev/docs/test-fixtures) * and using custom test fixtures. * * ```typescript * import { useFixtures } from '@serenity-js/playwright-test' * import { Log } from '@serenity-js/core' * * const { describe, it } = useFixtures<{ message: string }>({ * message: 'Hello world!' * }) * * describe('Serenity/JS useFixtures', () => { * * it('enables injecting custom test fixtures into test scenarios', async ({ actor, message }) => { * await actor.attemptsTo( * Log.the(message), * ) * }) * }) * ``` * * Shorthand for [`useBase`](https://serenity-js.org/api/playwright-test/function/useBase/) */ useFixtures: <T extends Record<string, any>, W extends Record<string, any> = object>(customFixtures: Fixtures<T, W, TestArgs, WorkerArgs>) => TestApi<TestArgs & T, WorkerArgs & W>; it: TestType<TestArgs, WorkerArgs>; test: TestType<TestArgs, WorkerArgs>; }; /** * Declares a single test scenario. * * ## Example * * ```typescript * import { Ensure, equals } from '@serenity-js/assertions' * import { describe, it } from '@serenity-js/playwright-test' * * describe(`Todo List App`, () => { * * it(`should allow me to add a todo item`, async ({ actor }) => { * await actor.attemptsTo( * startWithAnEmptyList(), * * recordItem('Buy some milk'), * * Ensure.that(itemNames(), equals([ * 'Buy some milk', * ])), * ) * }) * * it('supports multiple actors using separate browsers', async ({ actorCalled }) => { * await actorCalled('Alice').attemptsTo( * startWithAListContaining( * 'Feed the cat' * ), * ) * * await actorCalled('Bob').attemptsTo( * startWithAListContaining( * 'Walk the dog' * ), * ) * * await actorCalled('Alice').attemptsTo( * Ensure.that(itemNames(), equals([ * 'Feed the cat' * ])), * ) * * await actorCalled('Bob').attemptsTo( * Ensure.that(itemNames(), equals([ * 'Walk the dog' * ])), * ) * }) * }) * ``` * * ## Learn more * - [Grouping test scenarios](https://serenity-js.org/api/playwright-test/function/describe/) * - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/) * - [Playwright Test `test` function](https://playwright.dev/docs/api/class-test#test-call) * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/) */ export declare const it: TestType<PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures, PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures>; /** * Declares a single test scenario. Alias for [`it`](https://serenity-js.org/api/playwright-test/function/it/). */ export declare const test: TestType<PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures, PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures>; /** * Declares a group of test scenarios. * * ## Example * * ```typescript * import { Ensure, equals } from '@serenity-js/assertions' * import { describe, it, test } from '@serenity-js/playwright-test' * import { Photographer, TakePhotosOfFailures, Value } from '@serenity-js/web' * * describe(`Todo List App`, () => { * * test.use({ * defaultActorName: 'Serena', * crew: [ * Photographer.whoWill(TakePhotosOfFailures), * ], * }) * * it(`should allow me to add a todo item`, async ({ actor }) => { * await actor.attemptsTo( * startWithAnEmptyList(), * * recordItem('Buy some milk'), * * Ensure.that(itemNames(), equals([ * 'Buy some milk', * ])), * ) * }) * * it('should clear text input field when an item is added', async ({ actor }) => { * await actor.attemptsTo( * startWithAnEmptyList(), * * recordItem('Buy some milk'), * * Ensure.that(Value.of(newTodoInput()), equals('')), * ) * }) * }) * ``` * * ## Learn more * - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/) * - [Playwright Test `describe` function](https://playwright.dev/docs/api/class-test#test-describe-1) * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/) */ export declare const describe: { (title: string, callback: () => void): void; (callback: () => void): void; (title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; only(title: string, callback: () => void): void; only(callback: () => void): void; only(title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; skip(title: string, callback: () => void): void; skip(callback: () => void): void; skip(title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; fixme(title: string, callback: () => void): void; fixme(callback: () => void): void; fixme(title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; serial: { (title: string, callback: () => void): void; (callback: () => void): void; (title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; only(title: string, callback: () => void): void; only(callback: () => void): void; only(title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; }; parallel: { (title: string, callback: () => void): void; (callback: () => void): void; (title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; only(title: string, callback: () => void): void; only(callback: () => void): void; only(title: string, details: import("@playwright/test").TestDetails, callback: () => void): void; }; configure: (options: { mode?: "default" | "parallel" | "serial"; retries?: number; timeout?: number; }) => void; }; export declare const beforeAll: { (inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; (title: string, inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; }; export declare const beforeEach: { (inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; (title: string, inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; }; export declare const afterEach: { (inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; (title: string, inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; }; export declare const afterAll: { (inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; (title: string, inner: (args: PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures, testInfo: TestInfo) => Promise<any> | any): void; }; export declare const expect: Expect; export declare const useFixtures: <T extends Record<string, any>, W extends Record<string, any> = object>(customFixtures: Fixtures<T, W, PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures, PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures>) => TestApi<PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures & T, PlaywrightWorkerArgs & PlaywrightWorkerOptions & SerenityWorkerFixtures & W>; /** * Creates a Serenity/JS BDD-style test API around the given Playwright [base test](https://playwright.dev/docs/test-fixtures). * * ## Using default configuration * * When your test scenario doesn't require [custom test fixtures](https://playwright.dev/docs/test-fixtures), * and you're happy with the default [base test](https://playwright.dev/docs/api/class-test#test-call) offered by Playwright, * you can import test API functions such as [`describe`](https://serenity-js.org/api/playwright-test/function/describe/) and [`it`](https://serenity-js.org/api/playwright-test/function/describe/) directly from `@serenity-js/playwright-test`. * * ```typescript * import { describe, it, test } from '@serenity-js/playwright-test' * import { Log } from '@serenity-js/core' * * // override default fixtures if needed * test.use({ * defaultActorName: 'Alice' * }) * * describe('Serenity/JS default test API', () => { * * it('enables easy access to actors and standard Playwright fixtures', async ({ actor, browserName }) => { * await actor.attemptsTo( * Log.the(browserName), * ) * }) * }) * ``` * * In the above example, importing test API functions directly from `@serenity-js/playwright-test` is the equivalent of the following setup: * * ```typescript * import { test as playwrightBaseTest } from '@playwright/test' * import { useBase } from '@serenity-js/playwright-test' * * const { describe, it, test, beforeEach, afterEach } = useBase(playwrightBaseTest) * ``` * * ## Using custom fixtures * * When your test scenario requires [custom test fixtures](https://playwright.dev/docs/test-fixtures), * but you're still happy with the default [base test](https://playwright.dev/docs/api/class-test#test-call) offered by Playwright, * you can create fixture-aware test API functions such as [`describe`](https://serenity-js.org/api/playwright-test/function/describe/) and [`it`](https://serenity-js.org/api/playwright-test/function/describe/) * by calling [`useFixtures`](https://serenity-js.org/api/playwright-test/function/useFixtures/). * * For example, you can create a test scenario using a static `message` fixture as follows: * * ```typescript * import { useFixtures } from '@serenity-js/playwright-test' * import { Log } from '@serenity-js/core' * * const { describe, it } = useFixtures<{ message: string }>({ * message: 'Hello world!' * }) * * describe('Serenity/JS useFixtures', () => { * * it('enables injecting custom test fixtures into test scenarios', async ({ actor, message }) => { * await actor.attemptsTo( * Log.the(message), * ) * }) * }) * ``` * * The value of your test fixtures can be either static or dynamic and based on the value of other fixtures. * * To create a dynamic test fixture use the [function syntax](https://playwright.dev/docs/test-fixtures): * * ```typescript * import { Log } from '@serenity-js/core' * import { useFixtures } from '@serenity-js/playwright-test' * * const { describe, it } = useFixtures<{ message: string }>({ * message: async ({ actor }, use) => { * await use(`Hello, ${ actor.name }`); * } * }) * * describe('Serenity/JS useFixtures', () => { * * it('enables injecting custom test fixtures into test scenarios', async ({ actor, message }) => { * await actor.attemptsTo( * Log.the(message), * ) * }) * }) * ``` * * In the above example, creating test API functions via `useFixtures` is the equivalent of the following setup: * * ```typescript * import { test as playwrightBaseTest } from '@playwright/test' * import { useBase } from '@serenity-js/playwright-test' * * const { describe, it, test, beforeEach, afterEach } = useBase(playwrightBaseTest) * .useFixtures<{ message: string }>({ * message: async ({ actor }, use) => { * await use(`Hello, ${ actor.name }`); * } * }) * ``` * * ## Using custom base test * * In cases where you need to use a non-default base test, for example when doing [UI component testing](https://playwright.dev/docs/test-components), * you can create Serenity/JS test API functions around your preferred base test. * * ```tsx * import { test as componentTest } from '@playwright/experimental-ct-react' * import { Ensure, contain } from '@serenity-js/assertions' * import { useBase } from '@serenity-js/playwright-test' * import { Enter, PageElement, CssClasses } from '@serenity-js/web' * * import EmailInput from './EmailInput'; * * const { it, describe } = useBase(componentTest).useFixtures<{ emailAddress: string }>({ * emailAddress: ({ actor }, use) => { * use(`${ actor.name }@example.org`) * } * }) * * describe('EmailInput', () => { * * it('allows valid email addresses', async ({ actor, mount, emailAddress }) => { * const nativeComponent = await mount(<EmailInput/>); * * const component = PageElement.from(nativeComponent); * * await actor.attemptsTo( * Enter.theValue(emailAddress).into(component), * Ensure.that(CssClasses.of(component), contain('valid')), * ) * }) * }) * ``` * * @param baseTest */ export declare function useBase<BaseTestFixtures extends (PlaywrightTestArgs & PlaywrightTestOptions), BaseWorkerFixtures extends (PlaywrightWorkerArgs & PlaywrightWorkerOptions)>(baseTest: TestType<BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures & SerenityFixtures, BaseWorkerFixtures & SerenityWorkerFixtures>; export {}; //# sourceMappingURL=test-api.d.ts.map