Skip to main content

Actor

Actors represent people and external systems interacting with the system under test. Their role is to perform activities that demonstrate how to accomplish a given goal.

Actors are the core building block of the Screenplay Pattern, along with Abilities, Interactions, Tasks, and Questions. Actors are also the first thing you see in a typical Serenity/JS test scenario.

Learn more about:

Representing people and systems as actors

To use a Serenity/JS Actor, all you need is to say their name:

import { actorCalled } from '@serenity-js/core'

actorCalled('Alice')
// returns: Actor

Serenity/JS actors perform within the scope of a test scenario, so the first time you invoke actorCalled, Serenity/JS instantiates a new actor from the default Cast of actors (or any custom cast you might have configured). Any subsequent invocations of this function within the scope of the same test scenario retrieve the already instantiated actor, identified by their name.

import { actorCalled } from '@serenity-js/core'

actorCalled('Alice') // instantiates Alice
actorCalled('Bob') // instantiates Bob
actorCalled('Alice') // retrieves Alice, since she's already been instantiated

Serenity/JS scenarios can involve as many or as few actors as you need to model the given business workflow. For example, you might want to use multiple actors in test scenarios that model how different people perform different parts of a larger business process, such as reviewing and approving a loan application. It is also quite common to introduce supporting actors to perform administrative tasks, like setting up test data and environment, or audit tasks, like checking the logs or messages emitted to a message queue by the system under test.

The Stan Lee naming convention

Actor names can be much more than just simple identifiers like Alice or Bob. While you can give your actors any names you like, a good convention to follow is to give them names indicating the personae they represent or the role they play in the system.

Just like the characters in Stan Lee graphic novels, actors in Serenity/JS test scenarios are often given alliterate names as a mnemonic device. Names like “Adam the Admin”, “Edna the Editor”, “Trevor the Traveller”, are far more memorable than a generic “UI user” or “API user”. They’re also much easier for people to associate with the context, constraints, and affordances of the given actor.

Implements

Index

Constructors

constructor

Properties

publicreadonlyname

name: string

Methods

abilityTo

  • Retrieves actor’s Ability of abilityType, or one that extends abilityType.

    Please note that this method performs an instanceof check against abilities given to this actor via Actor.whoCan.

    Please also note that Actor.whoCan performs the same check when abilities are assigned to the actor to ensure the actor has at most one instance of a given ability type.


    Type parameters

    Parameters

    Returns T

attemptsTo

  • attemptsTo(...activities: Activity[]): Promise<void>
  • Instructs the actor to attempt to perform a number of activities, so either Tasks or Interactions), one by one.


    Parameters

    Returns Promise<void>

whoCan

  • Gives this Actor a list of abilities they can use to interact with the system under test or the test environment.

    @throws

    ConfigurationError Throws a ConfigurationError if the actor already has an ability of this type.


    Parameters

    • rest...abilities: Ability[]

      A vararg list of abilities to give the actor

    Returns Actor

    The actor with newly gained abilities

answer


  • Type parameters

    • T

    Parameters

    Returns Promise<T>

    The answer to the Answerable

collect

  • collect(artifact: Artifact, name?: string | Name): void
  • Makes the Actor collect an Artifact so that it can be included in the test report.

    Implementing a custom interaction to attach artifacts

    import * as fs from 'node:fs'
    import { Answerable, Interaction } from '@serenity-js/core'
    import { Path } from '@serenity-js/core/lib/io'
    import { Name, TextData } from '@serenity-js/core/lib/model'

    export class Attach {

    static contentsOf = (pathToFile: Path): Interaction =>
    Interaction.where(`#actor attaches contents of ${ pathToFile.basename() }`, async actor => {
    const data = fs.readFileSync(pathToFile.value).toString('utf-8');

    actor.collect(
    TextData.fromJSON({ contentType: 'text/plain', data }),
    new Name(pathToFile.basename()),
    )
    })

    static textData = (contents: Answerable<string>, name?: string): Interaction =>
    Interaction.where(`#actor attaches text data`, async actor => {
    const data = await actor.answer(contents);

    actor.collect(
    TextData.fromJSON({ contentType: 'text/plain', data }),
    name && new Name(name),
    )
    })
    }

    Attaching plain text

    import { actorCalled } from '@serenity-js/core'
    import { Path } from '@serenity-js/core/lib/io'

    actorCalled('Alice').attemptsTo(
    Attach.textData('some text', 'some name'),
    )

    Attaching contents of a text file

    import { actorCalled } from '@serenity-js/core'
    import { Log } from '@serenity-js/core'

    actorCalled('Alice').attemptsTo(
    Attach.contentsOf(Path.from(__dirname, 'output/server.log')),
    )

    Parameters

    • artifact: Artifact

      The artifact to be collected, such as JSONData

    • optionalname: string | Name

      The name of the artifact to make it easy to recognise in the test report

    Returns void

currentTime

  • Returns current time.


    Returns Timestamp

dismiss

  • dismiss(): Promise<void>

toString

  • toString(): string
  • Returns a human-readable, string representation of this actor and their abilities.

    PRO TIP: To get the name of the actor, use Actor.name


    Returns string