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

371 lines 17.2 kB
import type { Cast, ClassDescription, Duration, Serenity, StageCrewMember, StageCrewMemberBuilder } from '@serenity-js/core'; import type { Actor } from '@serenity-js/core'; import type { ExtraBrowserContextOptions } from '@serenity-js/playwright'; /** * Serenity/JS-specific [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures) * injected into your [test scenarios](https://serenity-js.org/api/playwright-test/function/it/). * * ### Configuring Serenity/JS using a test file * * ```typescript * import { Ensure, equals } from '@serenity-js/assertions' * import { describe, it, test } from '@serenity-js/playwright-test' * import { Photographer, TakePhotosOfFailures } from '@serenity-js/web' * * describe(`Recording items`, () => { * * test.use({ * defaultActorName: 'Serena', * crew: [ * Photographer.whoWill(TakePhotosOfFailures), * ], * * // Register a custom cast of Serenity/JS actors to replace the default one * actors: async ({ browser, contextOptions, extraContextOptions, baseURL }, use) => { * const cast = Cast.where(actor => * actor.whoCan( * BrowseTheWebWithPlaywright.using(browser, contextOptions, extraContextOptions), * TakeNotes.usingAnEmptyNotepad(), * CallAnApi.at(baseURL), * ) * ) * * await use(cast) * }, * }) * * 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', * ])), * ) * }) * }) * }) * ``` * * ### Configuring Serenity/JS using Playwright configuration file * * ```typescript * // playwright.config.ts * import { defineConfig } from '@playwright/test' * import type { Cast, TakeNotes } from '@serenity-js/core' * import type { BrowseTheWebWithPlaywright } from '@serenity-js/playwright' * import type { SerenityFixtures, SerenityWorkerFixtures } from '@serenity-js/playwright-test' * import type { CallAnApi } from '@serenity-js/rest' * * export default defineConfig<SerenityFixtures & MyCustomOptions, SerenityWorkerFixtures> = { * * // Register Serenity/JS reporter for Playwright Test * // to enable integration with Serenity/JS stage crew members * // and have them instantiated in the Playwright reporter process * reporter: [ * [ '@serenity-js/playwright-test', { * // Stage crew members instantiated in the test reporter process * crew: [ * '@serenity-js/serenity-bdd', * '@serenity-js/console-reporter', * [ '@serenity-js/core:ArtifactArchiver', { outputDirectory: 'target/site/serenity' } ], * ] * }] * ], * * use: { * * // Register Serenity/JS stage crew members * // and have them instantiated in Playwright Test worker processes * crew: [ * [ '@serenity-js/web:Photographer', { strategy: 'TakePhotosOfFailures' } ] * ], * * // Name to be given to an actor injected via `actor` fixture * defaultActorName: 'Alice', * * // Any other Playwright options * baseURL: 'https://todo-app.serenity-js.org/', * video: 'on-first-retry', * trace: 'on-first-retry', * }, * }) * ``` * * ## Learn more * - [Using Serenity/JS with Playwright Test](https://serenity-js.org/handbook/test-runners/playwright-test/) * - [`PlaywrightTestConfig`](https://serenity-js.org/api/playwright-test/#PlaywrightTestConfig) * - [`Cast`](https://serenity-js.org/api/core/class/Cast/) * - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/) */ export interface SerenityFixtures { /** * Configures the name given to the default Serenity/JS [`actor`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actor) * injected into a [test scenario](https://serenity-js.org/api/playwright-test/function/it/). * * #### Learn more * - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/) * - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/) */ defaultActorName: string; /** * Configures the [stage crew members](https://serenity-js.org/api/core/class/SerenityConfig/#crew) * to be instantiated in Playwright Test worker processes. * * :::info Did you know? * By default, Serenity/JS registers a [`Photographer`](https://serenity-js.org/api/web/class/Photographer/).whoWill([`TakePhotosOfFailures`](https://serenity-js.org/api/web/class/TakePhotosOfFailures/)), * so that any test failures are automatically accompanied by a screenshot. * * If you prefer a different behaviour, you can configure the `crew` with an empty array to disable taking screenshots altogether (`crew: []`), * or with a [`Photographer`](https://serenity-js.org/api/web/class/Photographer/) who uses a different [`PhotoTakingStrategy`](https://serenity-js.org/api/web/class/PhotoTakingStrategy/), like to [`TakePhotosOfInteractions`](https://serenity-js.org/api/web/class/TakePhotosOfInteractions/). * ::: * * #### Example * * ```typescript * // playwright.config.ts * import type { SerenityFixtures, SerenityWorkerFixtures } from '@serenity-js/playwright-test' * import { defineConfig } from '@playwright/test' * * export default defineConfig<SerenityFixtures, SerenityWorkerFixtures>({ * use: { * crew: [ * [ '@serenity-js/web:Photographer', { strategy: 'TakePhotosOfFailures' } ] * ], * }, * }); * ``` * * #### Learn more * - [`SerenityConfig.crew`](https://serenity-js.org/api/core/class/SerenityConfig/#crew) */ crew: Array<ClassDescription | StageCrewMember | StageCrewMemberBuilder>; /** * Sets the [`cueTimeout`](https://serenity-js.org/api/core/class/SerenityConfig/#cueTimeout) to a given [duration](https://serenity-js.org/api/core/class/Duration/) or a numeric value in milliseconds. * Defaults to **5 seconds**. * * #### Learn more * - [`SerenityConfig.cueTimeout`](https://serenity-js.org/api/core/class/SerenityConfig/#cueTimeout) * - [`Discardable`](https://serenity-js.org/api/core/interface/Discardable/) * - [`Ability`](https://serenity-js.org/api/core/class/Ability/) */ cueTimeout: number | Duration; /** * The maximum default amount of time allowed for interactions such as [`Wait.until`](https://serenity-js.org/api/core/class/Wait/#until) * to complete. * * Defaults to **5 seconds**, can be overridden per interaction. * * #### Learn more * - [`Wait.until`](https://serenity-js.org/api/core/class/Wait/#until) */ interactionTimeout: number | Duration; /** * Convenience properties to be used with the [ability](https://serenity-js.org/api/core/class/Ability/) * to [`BrowseTheWebWithPlaywright`](https://serenity-js.org/api/playwright/class/BrowseTheWebWithPlaywright/), * in addition to Playwright [BrowserContextOptions](https://playwright.dev/docs/api/class-testoptions#test-options-context-options): * * - [`defaultNavigationTimeout`](https://serenity-js.org/api/playwright/interface/ExtraBrowserContextOptions/#defaultNavigationTimeout) * - [`defaultNavigationWaitUntil`](https://serenity-js.org/api/playwright/interface/ExtraBrowserContextOptions/#defaultNavigationWaitUntil) * - [`defaultTimeout`](https://serenity-js.org/api/playwright/interface/ExtraBrowserContextOptions/#defaultTimeout) * * #### Using `extraContextOptions` with the default cast of Serenity/JS actors * * ```typescript * // playwright.config.ts * import type { SerenityFixtures, SerenityWorkerFixtures } from '@serenity-js/playwright-test' * import { defineConfig } from '@playwright/test' * * export default defineConfig<SerenityFixtures, SerenityWorkerFixtures>({ * use: { * extraContextOptions: { * defaultNavigationTimeout: 30_000, * } * * // Since `actors` property is not defined, * // `extraContextOptions` will be passed to the default cast of Serenity/JS actors * // and injected into the ability to `BrowseTheWebWithPlaywright` * // that each actor receives. * }, * }) * ``` * * #### Using `extraContextOptions` with a custom cast of Serenity/JS actors * * ```typescript * // playwright.config.ts * import type { SerenityFixtures, SerenityWorkerFixtures } from '@serenity-js/playwright-test' * import { defineConfig } from '@playwright/test' * * export default defineConfig<SerenityFixtures, SerenityWorkerFixtures>({ * use: { * extraContextOptions: { * defaultNavigationTimeout: 30_000, * } * * // Custom cast of actors receives the default `contextOptions` and * // the `extraContextOptions` with the additional Serenity/JS properties. * actors: async ({ browser, contextOptions, extraContextOptions }, use) => { * const cast = Cast.where(actor => actor.whoCan( * BrowseTheWebWithPlaywright.using(browser, contextOptions, extraContextOptions), * TakeNotes.usingAnEmptyNotepad(), * )) * * await use(cast) * }, * }, * }) * ``` * * #### Learn more * - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/) * - [Playwright Browser Context options](https://playwright.dev/docs/api/class-testoptions#test-options-context-options) * - [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures) */ extraContextOptions: Partial<ExtraBrowserContextOptions>; /** * A cast of Serenity/JS actors to be used instead of the default cast * when instantiating [`actor`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actor) * and invoking [`actorCalled`](https://serenity-js.org/api/playwright-test/interface/SerenityWorkerFixtures/#actorCalled). * * :::info Did you know? * When you use `@serenity-js/playwright-test` [test APIs](https://serenity-js.org/api/playwright-test/function/it/), Serenity/JS already provides a default cast of actors for you. * Each one of the default actors receives [abilities](https://serenity-js.org/api/core/class/Ability/) to [`BrowseTheWebWithPlaywright`](https://serenity-js.org/api/playwright/class/BrowseTheWebWithPlaywright/) and [`TakeNotes.usingAnEmptyNotepad`](https://serenity-js.org/api/core/class/TakeNotes/#usingAnEmptyNotepad). * * The default abilities should be sufficient in most web testing scenarios. However, you might want to override this default configuration * when you need your actors to [interact with REST APIs](https://serenity-js.org/api/rest/class/CallAnApi/), * [manage local servers](https://serenity-js.org/api/local-server/class/ManageALocalServer/), * start with a notepad that has some [initial state](https://serenity-js.org/api/core/class/TakeNotes/#using), * or receive [custom abilities](https://serenity-js.org/api/core/class/Ability/). * ::: * * * #### Overriding the default cast of Serenity/JS actors * * ```typescript * import { Cast, TakeNotes } from '@serenity-js/core' * import { Ensure, equals } from '@serenity-js/assertions' * import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright' * import { describe, it, test } from '@serenity-js/playwright-test' * * describe(`Recording items`, () => { * * test.use({ * extraContextOptions: { * defaultNavigationTimeout: 30_000, * }, * * defaultActorName: 'Serena', * actors: async ({ browser, contextOptions, extraContextOptions }, use) => { * const cast = Cast.where(actor => * actor.whoCan( * BrowseTheWebWithPlaywright.using(browser, contextOptions, extraContextOptions), * TakeNotes.usingAnEmptyNotepad(), * ) * ) * * // Make sure to pass your custom cast to Playwright `use` callback * await use(cast) * }, * }) * * 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', * ])), * ) * }) * }) * }) * * * #### Learn more * - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/) * - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/) */ actors: Cast; /** * Default [`actor`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actor) injected into a [test scenario](https://serenity-js.org/api/playwright-test/function/it/). * * Using `actor` fixture is equivalent to invoking [`actorCalled`](https://serenity-js.org/api/playwright-test/interface/SerenityWorkerFixtures/#actorCalled) * with [`defaultActorName`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#defaultActorName). * * #### Learn more * - [`actorCalled`](https://serenity-js.org/api/playwright-test/interface/SerenityWorkerFixtures/#actorCalled) * - [`defaultActorName`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#defaultActorName) * - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/) */ actor: Actor; } /** * Serenity/JS-specific worker-scope [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures) * injected into your [test scenarios](https://serenity-js.org/api/playwright-test/function/it/). * * ## Example test scenario * * ```typescript * import { Ensure, equals } from '@serenity-js/assertions' * import { beforeAll, describe, it } from '@serenity-js/playwright-test' * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest' * * describe('GitHub', () => { * * beforeAll('Ensure system is ready to test', async ({ actorCalled }) => { * await actorCalled('Stagehand') * .whoCan(CallAnApi.at('https://www.githubstatus.com/api/v2/')) * .attemptsTo( * Send.a(GetRequest.to('status.json')), * Ensure.that( * LastResponse.status(), * equals(200) * ), * Ensure.that( * LastResponse.body().status.description, * equals('All Systems Operational') * ), * ); * }); * }); * ``` * * ## Learn more * - [Using Serenity/JS with Playwright Test](https://serenity-js.org/handbook/test-runners/playwright-test/) */ export interface SerenityWorkerFixtures { /** * Name and version of the operating system that Playwright Test worker process runs on. */ platform: { name: string; version: string; }; /** * Retrieves the root object of the Serenity/JS framework. */ serenity: Serenity; /** * Uses the provided [cast](https://serenity-js.org/api/core/class/Cast/) of [`actors`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actors) to instantiate an [`Actor`](https://serenity-js.org/api/core/class/Actor/) called `name` * and inject it into a [test scenario](https://serenity-js.org/api/playwright-test/function/it/). * * Retrieves an existing actor if one has already been instantiated. * * #### Learn more * - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/) * - [`SerenityFixtures.actors`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actors) * * @param name */ actorCalled: (name: string) => Actor; } //# sourceMappingURL=serenity-fixtures.d.ts.map