Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk5 min

How to Use Web Selectors in WebdriverIO

Use WebdriverIO’s $ and $$ commands with CSS, text, XPath, accessible-name, or custom selectors. Choose stable locators, scope queries deliberately, and account for v9 Shadow DOM and BiDi behavior.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use WebdriverIO’s $ command to locate one element and $$ to locate multiple elements. CSS is the default selector strategy; WebdriverIO also supports text selectors, XPath, accessible-name selectors, and custom locator strategies. Prefer a selector that identifies the control’s purpose and is likely to survive changes to styling or page structure.

Start with $ and $$

WebdriverIO’s $ and $$ are element-query commands, not jQuery or Sizzle. Use $ when you expect one target and $$ when you want a collection of matches.

// Locate one element with a CSS selector (CSS is the default strategy).
const submit = await $('[data-testid="submit"]');

// Locate all matching elements.
const listItems = await $$('.results li');

Use a selector that distinguishes the intended element. A generic tag such as button can match several controls, while a styling class may change when the design changes. A dedicated test ID, accessible name, or suitable user-facing text can make the target clearer.

Choose a selector that fits the element

Strategy Example When it helps Trade-off to consider
CSS $('[data-testid="submit"]') Use the default strategy for IDs, attributes, classes, and structural relationships. Styling classes can be fragile; generic selectors may not uniquely identify the target.
Exact link text $('=WebdriverIO') Find a link by its exact text. Visible wording can change or be localized.
Partial link text $('*=driver') Find a link whose text includes the supplied string. Partial text may match more than one link.
Accessible name $('aria/Submit') Target a control by the name exposed to assistive technology. Behavior differs between BiDi-capable and Classic sessions; see the compatibility notes below.
XPath $('//ul/li[2]') Express a relationship in the document tree, such as selecting the second list item. Tree-dependent expressions can be harder to maintain if the structure changes.
Custom strategy browser.custom$('myStrategy', args) Apply an application-specific lookup rule that ordinary selectors do not express. Requires a registered strategy and a web environment where execute can run.

For a user-facing control, the official selector example recommends a specific button text such as button=Submit as its strongest example, and marks aria/Submit and a dedicated data-testid as good choices. It rates generic button and styling-based .btn.btn-large poorly in that example. These are context-dependent recommendations, not a guarantee that visible text is always stable: consider whether wording changes with localization, and use translation files when translated text could change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scope a query or combine strategies by chaining

Do not mix multiple selector strategies in a single selector string. If the target is inside a component, first locate the component, then query within it. Chaining can also combine strategies deliberately:

const select = await $('custom-datepicker').$('#calendar').$('aria/Select');

Every $ or $$ query attempts to locate elements. When one combined selector can identify the target clearly, prefer it over repeated lookups. Chain when it narrows the search to a meaningful parent or when moving from one selector strategy to another makes the query easier to understand.

Register a custom locator strategy when needed

For an application-specific rule, register a strategy with browser.addLocatorStrategy(name, function), then call browser.custom$ for one result or browser.custom$$ for multiple results. This example strategy uses document.querySelectorAll:

browser.addLocatorStrategy('myStrategy', (selector) => {
  return document.querySelectorAll(selector);
});

const oneMatch = await browser.custom$('myStrategy', '[data-testid="submit"]');
const allMatches = await browser.custom$$('myStrategy', '.result');

Custom strategies are for cases where the application’s lookup rule is not adequately expressed by ordinary selectors. They require a web context in which WebdriverIO can run execute.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Account for WebdriverIO version and session type

Shadow DOM in v9

WebdriverIO v9 automatically pierces Shadow DOM. The current selectors guide says the special >>> deep-selector prefix is no longer required, and recommends removing it when migrating.

aria/ selectors in BiDi and Classic sessions

In BiDi-capable browser sessions, WebdriverIO first uses browsingContext.locateNodes with an accessibility locator against the browser accessibility tree. If it finds no match, it falls back to a Classic XPath heuristic so existing queries can still match. Classic sessions use that XPath approximation directly; the guide warns this can be slower on large pages. Do not assume the same lookup path or performance across session types.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common selector problems and fixes

  • A selector matches the wrong element or several elements: make it more specific with a stable attribute, an accessible name, or an appropriate text selector; use $ when targeting one element and $$ when collecting matches.
  • A selector breaks after a visual redesign: replace classes used only for styling with a selector based on purpose, such as a test ID or accessible name, if the application provides one.
  • A text selector stops matching after translation or copy edits: check the rendered link text and consider whether localization is expected. Use an appropriate stable attribute instead when text is not a dependable identifier.
  • A mixed selector string does not work: WebdriverIO does not combine multiple strategies in one selector string; locate a parent and chain a child query using the second strategy.
  • An old deep selector is redundant in v9: remove the >>> prefix because v9 pierces Shadow DOM automatically.
  • aria/ lookup behaves differently across environments: confirm whether the session is BiDi-capable or Classic; the Classic XPath approximation may be slower on large pages.
  • A custom strategy cannot run: confirm it was registered with browser.addLocatorStrategy and that the lookup is being performed in a web environment where execute can run.

Keep queries clear and economical

WebdriverIO documentation recommends resilient selectors, targeting a single element where possible, and minimizing repeated queries. That does not mean every selector form has a universal speed ranking. The documented distinction is narrower: BiDi accessibility-tree lookup is typically faster than its Classic XPath approximation, while actual test behavior depends on the page and environment.

Or skip the browser setup

If your goal is a screenshot rather than an element interaction in a WebdriverIO test, ScreenshotNeo can return an image or PDF from one GET request. Its service removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. An MCP server lets AI agents use screenshot tools, and the free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Learn more at ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.