The els module provides low-level element manipulation functions for CodeceptJS tests, allowing for more granular control over element interactions and assertions. Elements are wrapped in a unified WebElement class that provides a consistent API across all helpers (Playwright, WebDriver, Puppeteer).
Note: For a comprehensive guide on element-based testing patterns and best practices, see Element-Based Testing.
Import the els functions in your test file:
import { element, eachElement, expectElement, expectAnyElement, expectAllElements } from 'codeceptjs/els'The element function allows you to perform custom operations on the first matching element found by a locator. It provides a low-level way to interact with elements when the built-in helper methods aren't sufficient.
element(purpose, locator, fn);
// or
element(locator, fn);purpose(optional) - A string describing the operation being performed. If omitted, a default purpose will be generated from the function.locator- A locator string/object to find the element(s).fn- An async function that receives the element as its argument and performs the desired operation.elargument is aWebElementwrapper providing a consistent API across all helpers.
Returns the result of the provided async function executed on the first matching element.
Scenario('my test', async ({ I }) => {
// combine element function with standard steps:
I.amOnPage('/cart');
// but use await every time you use element function
await element(
// with explicit purpose
'check custom attribute',
'.button',
async el => await el.getAttribute('data-test'),
);
// or simply
await element('.button', async el => {
return await el.isEnabled();
});
});- Only works with helpers that implement the
_locatemethod - The function will only operate on the first element found, even if multiple elements match the locator
- The provided callback must be an async function
- Throws an error if no helper with
_locatemethod is enabled
The eachElement function allows you to perform operations on each element that matches a locator. It's useful for iterating through multiple elements and performing the same operation on each one.
eachElement(purpose, locator, fn);
// or
eachElement(locator, fn);purpose(optional) - A string describing the operation being performed. If omitted, a default purpose will be generated from the function.locator- A locator string/object to find the element(s).fn- An async function that receives two arguments:el- The current element being processedindex- The index of the current element in the collection
Returns a promise that resolves when all elements have been processed. If any element operation fails, the function will throw the first encountered error.
Scenario('my test', async ({ I }) => {
// combine element function with standard steps:
I.click('/hotels');
// iterate over elements but don't forget to put await
await eachElement(
'validate list items', // explain your actions for future review
'.list-item', // locator
async (el, index) => {
const text = await el.getText();
console.log(`Item ${index}: ${text}`);
},
);
// Or simply check if all checkboxes are checked
await eachElement('input[type="checkbox"]', async el => {
const checked = await el.getProperty('checked');
if (!checked) {
throw new Error('Found unchecked checkbox');
}
});
});- Only works with helpers that implement the
_locatemethod - The function will process all elements that match the locator
- The provided callback must be an async function
- If an operation fails on any element, the error is logged and the function continues processing remaining elements
- After all elements are processed, if any errors occurred, the first error is thrown
- Throws an error if no helper with
_locatemethod is enabled
The expectElement function allows you to perform assertions on the first element that matches a locator. It's designed for validating element properties or states and will throw an assertion error if the condition is not met.
expectElement(locator, fn);locator- A locator string/object to find the element(s).fn- An async function that receives the element as its argument and should return a boolean value:true- The assertion passedfalse- The assertion failed
Returns a promise that resolves when the assertion is complete. Throws an assertion error if the condition is not met.
// Check if a button is enabled
await expectElement('.submit-button', async el => {
return await el.isEnabled();
});
// Verify element has specific text content
await expectElement('.header', async el => {
const text = await el.getText();
return text === 'Welcome';
});
// Check for specific attribute value
await expectElement('#user-profile', async el => {
const role = await el.getAttribute('role');
return role === 'button';
});- Only works with helpers that implement the
_locatemethod - The function will only check the first element found, even if multiple elements match the locator
- The provided callback must be an async function that returns a boolean
- The assertion message will include both the locator and the function used for validation
- Throws an error if no helper with
_locatemethod is enabled
The expectAnyElement function allows you to perform assertions where at least one element from a collection should satisfy the condition. It's useful when you need to verify that at least one element among many matches your criteria.
expectAnyElement(locator, fn);locator- A locator string/object to find the element(s).fn- An async function that receives the element as its argument and should return a boolean value:true- The assertion passed for this elementfalse- The assertion failed for this element
Returns a promise that resolves when the assertion is complete. Throws an assertion error if no elements satisfy the condition.
Scenario('validate any element matches criteria', async ({ I }) => {
// Navigate to the page
I.amOnPage('/products');
// Check if any product is marked as "in stock"
await expectAnyElement('.product-item', async el => {
const status = await el.getAttribute('data-status');
return status === 'in-stock';
});
// Verify at least one price is below $100
await expectAnyElement('.price-tag', async el => {
const price = await el.getText();
return parseFloat(price.replace('$', '')) < 100;
});
// Check if any button in the list is enabled
await expectAnyElement('.action-button', async el => {
return await el.isEnabled();
});
});- Only works with helpers that implement the
_locatemethod - The function will check all matching elements until it finds one that satisfies the condition
- Stops checking elements once the first matching condition is found
- The provided callback must be an async function that returns a boolean
- Throws an assertion error if no elements satisfy the condition
- Throws an error if no helper with
_locatemethod is enabled
The expectAllElements function verifies that every element matching the locator satisfies the given condition. It's useful when you need to ensure that all elements in a collection meet specific criteria.
expectAllElements(locator, fn);locator- A locator string/object to find the element(s).fn- An async function that receives the element as its argument and should return a boolean value:true- The assertion passed for this elementfalse- The assertion failed for this element
Returns a promise that resolves when all assertions are complete. Throws an assertion error as soon as any element fails the condition.
Scenario('validate all elements meet criteria', async ({ I }) => {
// Navigate to the page
I.amOnPage('/dashboard');
// Verify all required fields have the required attribute
await expectAllElements('.required-field', async el => {
const required = await el.getAttribute('required');
return required !== null;
});
// Check if all checkboxes in a form are checked
await expectAllElements('input[type="checkbox"]', async el => {
const checked = await el.getProperty('checked');
return checked === true;
});
// Verify all items in a list have non-empty text
await expectAllElements('.list-item', async el => {
const text = await el.getText();
return text.trim().length > 0;
});
// Ensure all buttons in a section are enabled
await expectAllElements('#action-section button', async el => {
return await el.isEnabled();
});
});- Only works with helpers that implement the
_locatemethod - The function checks every element that matches the locator
- Fails fast: stops checking elements as soon as one fails the condition
- The provided callback must be an async function that returns a boolean
- The assertion message will include which element number failed (e.g., "element #2 of...")
- Throws an error if no helper with
_locatemethod is enabled
Elements passed to your callbacks are wrapped in a WebElement class that provides a consistent API across all helpers. For complete documentation of the WebElement API, see WebElement.
Quick reference of available methods:
await element('.my-element', async el => {
// Get element information
const text = await el.getText()
const attr = await el.getAttribute('data-value')
const prop = await el.getProperty('value')
const html = await el.getInnerHTML()
// Check state
const visible = await el.isVisible()
const enabled = await el.isEnabled()
const exists = await el.exists()
// Interactions
await el.click()
await el.type('text')
// Child elements
const child = await el.$('.child')
const children = await el.$$('.child')
// Position
const box = await el.getBoundingBox()
// Native access
const helper = el.getHelper()
const native = el.getNativeElement()
})