DEV Community

Cover image for Screenplay Pattern for Test automation: Actions - What an user can do
Will Drygla
Will Drygla

Posted on

Screenplay Pattern for Test automation: Actions - What an user can do

🎬 Screenplay Pattern - Part 2: Actions
In the Screenplay pattern, once you've defined your actor, the next question is:
What can this actor do?

That's where Actions come in.

🛠️ What are Actions?
Actions are the building blocks of your test.
They define how an actor interacts with the system — but in a reusable and readable way.

Instead of spreading low-level commands all over your tests, you create named tasks that express intention, like:

   bankCustomer.makeAction('enterLoginCredentials', {
                email: validUser.email,
                password: validUser.password,
            });
Enter fullscreen mode Exit fullscreen mode

It tells you exactly what’s happening — not how it’s implemented.

How the actions works:

  • I use an class for each feature of our system:
export class LoginActions {
    enterLoginCredentials(input: { email?: string; password?: string }) {
        loginPage.waitForPageToLoad();

        if (input.email) {
            cy.get(loginPage.getEmailInputSelector())
                .filter(':visible')
                .should('be.enabled')
                .clear()
                .type(input.email, { delay: 50 });
        }

        if (input.password) {
            cy.get(loginPage.getPasswordInputSelector())
                .filter(':visible')
                .should('be.enabled')
                .clear()
                .type(input.password, { delay: 50 });
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The UI selectors are stored in a separate file. By keeping selectors in their own file, they can be reused across different actions.

After this, the actors who can perform this actions, only need:

export default class BankCustomer extends BaseActor {
    constructor() {
        const loginActions = new LoginActions();

        super(loginActions);
    }
}
Enter fullscreen mode Exit fullscreen mode

So when you read a test and see an action, it tells you what is being done — not how it's done. If you want to check the implementation, just search for the action name or look it up in the documentation. (Screenplay makes documenting tests easier — more on that later!)

âś… Why use Actions?
Readable: Your test reads like a user story.

Reusable: One action can be used across many scenarios.

Maintainable: If the UI changes, you update the action, not every test.

In short:
Actions help you write tests that describe behavior, not code.
They're a key piece in making automation feel like a conversation between the user and the system.

Next post: ❓Questions – how do we verify what happened?

Top comments (0)