UNPKG

@serenity-js/core

Version:

The core Serenity/JS framework, providing the Screenplay Pattern interfaces, as well as the test reporting and integration infrastructure

268 lines 8.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TakeNotes = void 0; const abilities_1 = require("../abilities"); const Notepad_1 = require("./Notepad"); /** * An [`Ability`](https://serenity-js.org/api/core/class/Ability/) that enables an [`Actor`](https://serenity-js.org/api/core/class/Actor/) to remember information * to be recalled during a test scenario. * * Under the hood, [`TakeNotes`](https://serenity-js.org/api/core/class/TakeNotes/) uses a [`Notepad`](https://serenity-js.org/api/core/class/Notepad/), which state * can be populated both during initialisation or while the test scenario is executed. * Populating the notepad when it's initialised can be useful to associate authentication credentials * or personal details with a given actor, while dynamic recording of notes during a test scenario * can be useful when the data to be recorded is not known upfront - for example when we want * the actor to remember a JWT stored in the browser and then use it when sending API requests. * * **Pro tip:** [`TakeNotes`](https://serenity-js.org/api/core/class/TakeNotes/), [`Notepad`](https://serenity-js.org/api/core/class/Notepad/) and [`notes`](https://serenity-js.org/api/core/function/notes/) can be typed * using [TypeScript generics](https://www.typescriptlang.org/docs/handbook/2/generics.html) * to help you avoid typos when specifying note names. * * See [notes](https://serenity-js.org/api/core/function/notes) and [`Notepad`](https://serenity-js.org/api/core/class/Notepad/) for more usage examples. * * ## Remembering and retrieving a value * * ```ts * import { actorCalled, Log, notes, TakeNotes } from '@serenity-js/core' * * await actorCalled('Leonard') * .whoCan(TakeNotes.usingAnEmptyNotepad()) * .attemptsTo( * notes().set('my_note', 'some value'), * Log.the(notes().get('my_note')), * // emits 'some value' * ) * ``` * * ## Using generics * * ```ts * import { actorCalled, Log, notes, TakeNotes } from '@serenity-js/core' * * interface MyNotes { * personalDetails: { * firstName: string; * lastName: string; * } * } * * await actorCalled('Leonard') * .whoCan(TakeNotes.usingAnEmptyNotepad<MyNotes>()) * .attemptsTo( * Log.the(notes<MyNotes>().has('personalDetails')), * // emits false * * Log.the(notes<MyNotes>().get('personalDetails').isPresent()), * // emits false * * notes<MyNotes>().set('personalDetails', { firstName: 'Leonard', lastName: 'McLaud' }), * * Log.the(notes<MyNotes>().has('personalDetails')), * // emits true * * Log.the(notes<MyNotes>().get('personalDetails').isPresent()), * // emits true * * Log.the(notes().get('personalDetails').firstName), * // emits 'Leonard' * * Log.the(notes().get('personalDetails').firstName.toLocaleUpperCase()), * // emits 'LEONARD' * ) * ``` * * ## Populating the notepad with initial state * * ```ts * import { actorCalled, Log, Note, Notepad, TakeNotes } from '@serenity-js/core' * * interface MyNotes { * firstName: string; * lastName: string; * } * * await actorCalled('Leonard') * .whoCan( * TakeNotes.using(Notepad.with<MyNotes>({ * firstName: 'Leonard', * lastName: 'McLaud', * })) * ) * .attemptsTo( * notes<MyNotes>().set('lastName', 'Shelby'), * Log.the(notes().get('firstName')), * // emits 'Leonard' * * Log.the(notes().get('lastName')), * // emits 'Shelby' * ) * ``` * * ## Recording a dynamic note * * ```ts * import { actorCalled, Log, Notepad, notes, TakeNotes } from '@serenity-js/core' * import { By, Text, PageElement } from '@serenity-js/web' * import { BrowseTheWebWithWebdriverIO } from '@serenity-js/webdriverio' * * interface OnlineShoppingNotes { * promoCode: string; * } * * const promoCodeBanner = () => * PageElement.located(By.css('[data-testid="promo-code"]')) * .describedAs('promo code'); * * const promoCodeInput = () => * PageElement.located(By.css('[data-testid="promo-code-input"]')) * .describedAs('promo code field'); * * await actorCalled('Leonard') * .whoCan( * BrowseTheWebWithWebdriverIO.using(browser), * TakeNotes.using(Notepad.empty<OnlineShoppingNotes>()) * ) * .attemptsTo( * notes<OnlineShoppingNotes>().set('promoCode', Text.of(promoCode()), * // ... * Enter.theValue(notes<OnlineShoppingNotes>().get('promoCode')) * .into(promoCodeInput()) * ) * ``` * * ## Clearing a notepad before each test scenario (Mocha) * * ```ts * import 'mocha'; * * beforeEach(() => * actorCalled('Leonard') * .attemptsTo( * notes().clear(), * )) * ``` * * ## Clearing a notepad before each test scenario (Cucumber) * * ```ts * import { Before } from '@cucumber/cucumber' * * Before(() => * actorCalled('Leonard') * .attemptsTo( * notes().clear(), * )); * ``` * * ## Importing notes from an API response * * ```ts * // given an example API: * // GET /generate-test-user * // which returns: * // { "first_name": "Leonard", "last_name": "Shelby" } * * import { actorCalled, Log, Notepad, notes, TakeNotes } from '@serenity-js/core' * import { CallAnApi, GetRequest, Send } from '@serenity-js/rest' * * interface PersonalDetails { * first_name: string; * last_name: string; * } * * interface MyNotes { * personalDetails?: PersonalDetails; * } * * await actorCalled('Leonard') * .whoCan( * CallAnApi.at('https://api.example.org/'), * TakeNotes.using(Notepad.empty<MyNotes>()) * ) * .attemptsTo( * Send.a(GetRequest.to('/generate-test-user')), * notes<MyNotes>().set('personalDetails', LastResponse.body<PersonalDetails>()), * * Log.the(notes<MyNotes>().get('personalDetails').first_name), // emits 'Leonard' * Log.the(notes<MyNotes>().get('personalDetails').last_name), // emits 'Shelby' * ) * ``` * * ## Using the QuestionAdapter * * ```ts * import { actorCalled, Log, Notepad, notes, TakeNotes } from '@serenity-js/core' * * interface AuthCredentials { * username?: string; * password?: string; * } * * interface MyNotes { * auth: AuthCredentials; * } * * await actorCalled('Leonard') * .whoCan( * TakeNotes.using( * Notepad.with<MyNotes>({ // typed initial state * auth: { * username: 'leonard@example.org', * password: 'SuperSecretP@ssword!', * } * }) * ) * ) * .attemptsTo( * Log.the( * notes<MyNotes>() // typed notes * .get('auth') // returns QuestionAdapter<AuthCredentials> * .password // returns QuestionAdapter<string> * .charAt(0) * .toLocaleLowerCase(), // emits "s" * ), * ) * ``` * * ## Learn more * * - [notes](https://serenity-js.org/api/core/function/notes) * - [`Notepad`](https://serenity-js.org/api/core/class/Notepad/) * * @group Notes */ class TakeNotes extends abilities_1.Ability { notepad; /** * Initialises an [`Ability`](https://serenity-js.org/api/core/class/Ability/) to [`TakeNotes`](https://serenity-js.org/api/core/class/TakeNotes/) with [`Notepad.empty`](https://serenity-js.org/api/core/class/Notepad/#empty). */ static usingAnEmptyNotepad() { return TakeNotes.using(Notepad_1.Notepad.empty()); } /** * Initialises an [`Ability`](https://serenity-js.org/api/core/class/Ability/) to [`TakeNotes`](https://serenity-js.org/api/core/class/TakeNotes/) using * a [`Notepad.with`](https://serenity-js.org/api/core/class/Notepad/#with) some initial state. * * @param notepad */ static using(notepad) { return new TakeNotes(notepad); } /** * @param notepad */ constructor(notepad) { super(); this.notepad = notepad; } toJSON() { return { ...super.toJSON(), options: { notepad: this.notepad.toJSON(), } }; } } exports.TakeNotes = TakeNotes; //# sourceMappingURL=TakeNotes.js.map