liveBook · Manning

PageElement

As explained in BDD in Action, Second Edition

PageElement is a Serenity/JS web API abstraction representing an element located within a web page and supporting composable interactions and questions.

A registration test needs to check a temporary notification. The notification appears after a short animation, and its message is an HTML element inside a toaster widget. PageElement gives the test a reusable way to identify that element, rather than embedding its selector in every interaction or assertion. section 15.1.7 section 15.2.2

PageElement represents one web element. Define it with PageElement.located and a By selector, such as By.css or By.xpath; add describedAs to give interactions a useful reporting label. A selector can locate an element in the current browser tab or frame, or .of(parent) can locate it within another PageElement. Chaining is useful when several matching elements appear on a page or the containing element is determined at runtime. section 15.2.2

import { By, PageElement } from '@serenity-js/web'
 
const Toaster = () =>                            
    PageElement.located(By.css(`.ngx-toastr`))        #1
        .describedAs(`toaster`)
 
const ToasterMessage = () =>
    PageElement.located(By.css(`.toast-message`))     #2
        .of(Toaster())                                #3
        .describedAs('message')

This definition locates the message within the toaster instead of relying on one selector for the entire relationship. section 15.2.2

The same PageElement can be composed with interactions and questions: Click.on(element) acts on it, while Text.of(element) asks for its text. An assertion can check either the element itself with isPresent() or its text with includes(...). In the registration scenario, a verification task can wait for the message, check its content, click to dismiss it, and wait for it to disappear. Keeping that sequence in a task leaves the Cucumber step focused on the expected outcome. section 15.1.7 section 15.2.5

Ensure.that(Toaster.message(), isPresent())
Ensure.that(Text.of(Toaster.message()), includes('registered 
 successfully'))

These assertions show the distinction between asking whether an element is present and asking whether its text contains the expected message. section 15.2.5

PageElement definitions are independent of the chosen web integration tool. Serenity/JS translates By selectors for the configured tool and obtains the appropriate PageElement implementation through its web integration modules. The tool-specific BrowseTheWeb ability is configured for the actors; tests use PageElement.located rather than calling Playwright- or WebdriverIO-specific element classes directly. section 15.2.2 section 15.2.7

How BDD in Action, Second Edition covers it

How deep it goes
Shows selector-based and parent-relative definitions, then composes elements with interactions and questions; defers tool-specific implementations to integration modules.
Examples
Uses a registration toaster’s HTML, nested message selectors, presence and text assertions, and dismissal after verification.
What it assumes
Assumes familiarity with HTML and test scenarios while introducing PageElement and its selector-based definitions.
What you can do after
Apply it via @serenity-js/web to locate elements and compose portable clicks, text questions, and assertions.
How it connects
Connects PageElement to By selectors, the Screenplay Pattern, questions, assertions, and BrowseTheWeb abilities.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of BDD in Action, Second Edition. The section links point to the parts of the book it draws on.