Skip to main content

TakeNotes <Notes_Type>

An Ability that enables an Actor to remember information to be recalled during a test scenario.

Under the hood, TakeNotes uses a 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, Notepad and notes can be typed using TypeScript generics to help you avoid typos when specifying note names.

See notes and Notepad for more usage examples.

Remembering and retrieving a value

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

 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

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

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)

import 'mocha';

beforeEach(() =>
actorCalled('Leonard')
.attemptsTo(
notes().clear(),
))

Clearing a notepad before each test scenario (Cucumber)

import { Before } from '@cucumber/cucumber'

Before(() =>
actorCalled('Leonard')
.attemptsTo(
notes().clear(),
));

Importing notes from an API response

 // 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

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

Hierarchy

Index

Constructors

Properties

Methods

Constructors

constructor

  • Type parameters

    • Notes_Type: Record<any, any>

    Parameters

    Returns TakeNotes<Notes_Type>

Properties

publicreadonlynotepad

notepad: Notepad<Notes_Type>

Methods

staticusingAnEmptyNotepad

staticusing