Skip to content

Actors

An Actor is the central figure in the Screenplay pattern. Every test action flows through an Actor: they perform Tasks, exercise Abilities, remember Facts, and ask Questions.

Creating Actors

Use the Actor.named() factory method:

from screenwright import Actor

ali = Actor.named("Ali", description="a scrum master")

The description is optional but recommended. It appears in the test report alongside the Actor's name, making scenarios easier to understand.

Granting Abilities

Abilities represent what an Actor can do. Grant them with who_can():

from screenwright import Ability


class BrowseTheWeb(Ability):
    def __init__(self, driver):
        self.driver = driver

    @staticmethod
    def using(driver):
        return BrowseTheWeb(driver)


ali.who_can(BrowseTheWeb.using(driver))

You can grant multiple Abilities at once:

ali.who_can(
    BrowseTheWeb.using(driver),
    AuthenticateWithAPI.using(api_client),
)

The who_can() method returns the Actor, so you can chain it with other calls:

ali = (
    Actor.named("Ali", description="a scrum master")
    .who_can(BrowseTheWeb.using(driver))
    .remembers(username="admin")
)

Retrieving Abilities

Retrieve an Ability by its type with ability_to():

driver = ali.ability_to(BrowseTheWeb).driver

If the Actor does not have the requested Ability, an AbilityNotFoundError is raised.

You can check whether an Actor has an Ability without raising:

if ali.has_ability_to(BrowseTheWeb):
    driver = ali.ability_to(BrowseTheWeb).driver

Remembering Facts

Facts are key-value pairs that an Actor stores and recalls during a scenario:

ali.remembers(username="admin", role="scrum_master")

The remembers() method returns the Actor for fluent chaining.

Recalling Facts

Retrieve a stored Fact by key:

username = ali.recalls("username")  # "admin"

If the Actor does not remember the requested Fact, a FactNotFoundError is raised.

Performing Tasks and Interactions

Use attempts_to() to perform one or more Tasks or Interactions:

ali.attempts_to(
    Navigate.to("/dashboard"),
    Click.on(SETTINGS_LINK),
)

See Tasks & Interactions for details on creating performables.

Asking Questions

Use should_see_that() to ask a Question and verify the answer:

ali.should_see_that(DashboardTitle(), "Welcome, Ali")

The second argument can be either a literal value (compared with ==) or a callable predicate:

ali.should_see_that(ItemCount(), lambda count: count > 0)

See Questions for details.

Actors on the Stage

In a typical pytest-bdd test, you do not create Actors directly. Instead, you use the Stage to manage Actor lifecycle:

@given("Ali is a registered user")
def ali(stage):
    return stage.actor_named("Ali", description="a registered user")

The Stage ensures that each Actor is created once per scenario, wired up with the event publisher, and cleaned up when the scenario ends. See Stage & Scene for details.

Events Emitted

Every Actor action emits a domain event:

Action Event
Actor enters the Stage ActorEnteredStage
Ability granted AbilityGranted
Fact remembered FactRemembered
Task started TaskStarted
Task completed TaskCompleted
Task failed TaskFailed
Interaction started InteractionStarted
Interaction completed InteractionCompleted
Interaction failed InteractionFailed
Question asked QuestionAsked
Question answered QuestionAnswered
Actor exits the Stage ActorExitedStage

These events are collected and rendered into the cinematic HTML report.