Skip to main content

The Element Object

An Element Object is an object representing an element on the remote user agent, e.g. a DOM Node when running a session within a browser or a mobile element for mobile. It can be received using one of the many element query commands, e.g. $, custom$, react$ or shadow$.

Properties

An element object has the following properties:

NameTypeDetails
sessionIdStringSession id assigned from the remote server.
elementIdStringAssociated web element reference that can be used to interact with the element on the protocol level
selectorStringSelector used to query the element.
parentObjectEither the Browser Object when element was fetched from the it (e.g. const elem = browser.$('selector')) or an Element Object if it was fetched from an element scope (e.g. elem.$('selector'))
optionsObjectWebdriverIO options depending on how the browser object was created. See more setup types.

Methods

An element object provides all methods from the protocol section, e.g. WebDriver protocol as well as commands listed within the element section. Available protocol commands depend on the type of session. If you run an automated browser session, none of the Appium commands will be available and vice versa.

In addition to that the following commands are available:

NameParametersDetails
addCommand- commandName (Type: String)
- fn (Type: Function)
Allows to define custom commands that can be called from the browser object for composition purposes. Read more in the Custom Command guide.
overwriteCommand- commandName (Type: String)
- fn (Type: Function)
Allows to overwrite any browser command with custom functionality. Use carefully as it can confuse framework users. Read more in the Custom Command guide.

Remarks

Element Chain

When working with elements WebdriverIO provides special syntax to simplify querying them and composite complex nested element lookups. As element objects allow you to find elements within their tree branch using common query methods, users can fetch nested elements as follows:

const header = await $('#header')
const headline = await header.$('#headline')
console.log(await headline.getText()) // outputs "I am a headline"

With deep nested structures assigning any nested element to an array to then use it can be quite verbose. Therefore WebdriverIO has the concept of chained element queries that allow fetching nested elements like this:

console.log(await $('#header').$('#headline').getText())

This also works when fetching a set of elements, e.g.:

// get the text of the 3rd headline within the 2nd header
console.log(await $$('#header')[1].$$('#headline')[2].getText())

When working with a set of elements this can be especially useful when trying to interact with them, so instead of doing:

const elems = await $$('div')
const locations = await Promise.all(
elems.map((el) => el.getLocation())
)

You can directly call Array methods on the element chain, e.g.:

const location = await $$('div').map((el) => el.getLocation())

same as:

const divs = await $$('div')
const location = await divs.map((el) => el.getLocation())

WebdriverIO uses a custom implementation that supports asynchronous iterators under the hood so all commands from their API are also supported for these use cases.

Note: all async iterators return a promise even if your callback doesn't return one, e.g.:

const divs = await $$('div')
console.log(divs.map((div) => div.selector)) // ❌ returns "Promise<string>[]"
console.log(await divs.map((div) => div.selector)) // ✅ returns "string[]"

Custom Commands

You can set custom commands on the browser scope to abstract away workflows that are commonly used. Check out our guide on Custom Commands for more information.

Welcome! How can I help?

WebdriverIO AI Copilot