UNPKG

@serenity-js/web

Version:

Serenity/JS Screenplay Pattern library offering a flexible, web driver-agnostic approach for interacting with web-based user interfaces and components, suitable for various testing contexts

163 lines 6.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Switch = void 0; const core_1 = require("@serenity-js/core"); /** * Instructs an [actor](https://serenity-js.org/api/core/class/Actor/) who has the [ability](https://serenity-js.org/api/core/class/Ability/) to [`BrowseTheWeb`](https://serenity-js.org/api/web/class/BrowseTheWeb/) * to switch the context for future activities to a [`Switchable`](https://serenity-js.org/api/web/interface/Switchable/), such as a [`Page`](https://serenity-js.org/api/web/class/Page/) or a [`PageElement`](https://serenity-js.org/api/web/class/PageElement/). * * Please note that when the [`PageElement`](https://serenity-js.org/api/web/class/PageElement/) implementing [`Switchable`](https://serenity-js.org/api/web/interface/Switchable/) represents an [`iframe`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe), * using [`Switch`](https://serenity-js.org/api/web/class/Switch/) will result in switching the top-level browsing context to that [`iframe`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). * * When the [`PageElement`](https://serenity-js.org/api/web/class/PageElement/) represents any other [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement), * using [`Switch`](https://serenity-js.org/api/web/class/Switch/) sets [`HTMLElement#focus`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) * on the specified element. Assuming it can be focused. * * **Note:** The focused element is the element which will receive keyboard [press](https://serenity-js.org/api/web/class/Press/) events by default. * * ## Perform activities in the context of an iframe * * ```ts * import { actorCalled } from '@serenity-js/core' * import { By, Click, Enter, PageElement, Switch } from '@serenity-js/web' * * // Lean Page Object describing a login form, embedded in an iframe * class LoginForm { * static iframe = () => * PageElement.located(By.css('iframe')) * .describedAs('login form') * * static usernameField = () => * PageElement.located(By.css('[data-testid="username"]')) * .describedAs('username field') * * static passwordField = () => * PageElement.located(By.css('[data-testid="password"]')) * .describedAs('password field') * * static submitButton = () => * PageElement.located(By.css('button[type="submit"]')) * .describedAs('submit button') * } * * await actorCalled('Francesca') * .attemptsTo( * Switch.to(LoginForm.iframe).and( * Enter.theValue('francesca@example.org').into(LoginForm.usernameField()), * Enter.theValue('correct-horse-battery-staple').into(LoginForm.passwordField()), * Click.on(LoginForm.submitButton()), * ) * ) * ``` * * ## Perform activities in the context of another page * * ```ts * import { actorCalled } from '@serenity-js/core' * import { Click, Enter, Switch } from '@serenity-js/web' * import { browser } from '@wdio/globals' * * await actorCalled('Francesca') * .whoCan(BrowseTheWebWithWebdriverIO.using(browser)) * .attemptsTo( * Switch.to(Page.whichName(startsWith('popup'))).and( * // perform some activities in the context of the new window * * // optionally, close the browser tab * Page.current().close(), * ), * * // Note that switching back to the original page happens automatically * // after the last activity from the list finishes * ) * ``` * * ## Perform activities in the context of a focused page element * * ```ts * import { Ensure, equals } from '@serenity-js/assertions' * import { actorCalled } from '@serenity-js/core' * import { Key, PageElement, Press, Switch, Value } from '@serenity-js/web' * import { browser } from '@wdio/globals' * * const inputField = () => * PageElement.located(By.css('input')); * * await actorCalled('Francesca') * .whoCan(BrowseTheWebWithWebdriverIO.using(browser)) * .attemptsTo( * Switch.to(inputField()).and( * Press.the('h', 'e', 'l', 'l', 'o'), * Press.the(Key.Tab), * ), * Ensure.that(Value.of(inputField()), equals('hello')) * ) * ``` * * ## Learn more * * - [`BrowseTheWeb`](https://serenity-js.org/api/web/class/BrowseTheWeb/) * - [`Switchable`](https://serenity-js.org/api/web/interface/Switchable/) * - [`SwitchableOrigin`](https://serenity-js.org/api/web/interface/SwitchableOrigin/) * * @group Activities */ class Switch extends core_1.Interaction { switchable; /** * Instructs the [`Actor`](https://serenity-js.org/api/core/class/Actor/) * to switch the context for future activities to a [`Switchable`](https://serenity-js.org/api/web/interface/Switchable/), * such as a [`Page`](https://serenity-js.org/api/web/class/Page/) or a [`PageElement`](https://serenity-js.org/api/web/class/PageElement/). * * @param switchable */ static to(switchable) { return new Switch(switchable); } constructor(switchable) { super((0, core_1.the) `#actor switches to ${switchable}`); this.switchable = switchable; } /** * Instructs the [`Actor`](https://serenity-js.org/api/core/class/Actor/) * to switch the context for future activities to a [`Switchable`](https://serenity-js.org/api/web/interface/Switchable/), * such as a [`Page`](https://serenity-js.org/api/web/class/Page/) or a [`PageElement`](https://serenity-js.org/api/web/class/PageElement/), * perform a sequence of `activities`, and then switch the context back. * * @param activities * A sequence of activities to perform */ and(...activities) { return new SwitchAndPerformActivities(this.switchable, activities); } /** * @inheritDoc */ async performAs(actor) { const switchable = await actor.answer(this.switchable); await switchable.switchTo(); } } exports.Switch = Switch; /** * @package */ class SwitchAndPerformActivities extends core_1.Task { switchable; activities; constructor(switchable, activities) { super((0, core_1.the) `#actor switches to ${switchable}`); this.switchable = switchable; this.activities = activities; } /** * @inheritDoc */ async performAs(actor) { const switchable = await actor.answer(this.switchable); const origin = await switchable.switchTo(); await actor.attemptsTo(...this.activities); await origin.switchBack(); } } //# sourceMappingURL=Switch.js.map