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
