Selector constructor

Selector queries begin with an invocation of the Selector() constructor.

Constructor arguments and options determine the initial results of the Selector query.

If you want to perform additional actions with the Selector query results, attach Selector methods to the Selector constructor.

Selector( init [, options] )
Parameter Type Description
init Function | String | Selector | Snapshot | Promise See Initialize the Selector
options (optional) Object See Selector Options.

Initialize the Selector

There are three ways to initialize a Selector.

Read the Selector Guide for an in-depth look at Element Selectors.

Create a Keyword-Based Selector

Keyword-Based Selectors filter the page in search of elements that match CSS keywords.

Selector('#some-element');

A few examples:

  • body matches the body element.
  • .login matches elements with the login class name.
  • #input matches the first element with the input ID.

Selector Keywords

TestCafe Selector keywords are syntactically identical to CSS Selectors. TestCafe actions can’t target pseudo-elements and require additional code to target the Shadow DOM.

Create a Function-Based Selector

Function-based Selectors execute a client-side function that traverses the DOM and returns one of the following objects:

  • A DOM node
  • An array of DOM nodes
  • A NodeList object
  • An HTMLCollection object
  • A null object
  • An undefined object

The function-based Selector below retrieves a string from localStorage and finds a DOM element with the identical ID:

const element = Selector(() => {
    const storedElementId = window.localStorage.storedElementId;
    return document.getElementById(storedElementId);
});

Function-based Selectors can have additional parameters:

const elementWithId = Selector(id => {
    return document.getElementById(id);
});

await t.click(elementWithId('buy'));

Create a Selector-Based Selector

You can create Selectors based on other Selectors. These copies inherit original Selectors’ queries, but do not inherit their return value.

The example code below creates a copy of the ctaButton Selector with a modified visibilityCheck option:

const ctaButton = Selector('.cta-button');
Selector(ctaButton, { visibilityCheck: true });

You can create a new Selector from a DOM Node Snapshot object returned by another Selector. These Selectors inherit the original Selector’s return value, but you can still override their options:

const topMenuSnapshot = await Selector('#top-menu')();
const visibleTopMenu = Selector(topMenuSnapshot, {
        visibilityCheck: true
    });

You can create a new Selector from a Selector Promise:

const elementWithIdOrClassName = Selector(value => {
    return document.getElementById(value) || document.getElementsByClassName(value);
});
const submitButton = Selector(elementWithIdOrClassName('main-element'));

Selector Options

Options

options.boundTestRun

Type: Object

The boundTestRun option binds the TestController object to a Node.js callback. This is necessary to execute Selectors inside the callback function.

For more information, see the Advanced Selector Techniques guide.

options.dependencies

Type: Object

Selector functions can access the properties of the dependencies object as variables.

Use the dependencies option if you want to share data with a Selector function, but do not want to pass it as an argument.

The following code example includes a Selector function that receives a server-side object (customId) as a dependency:

import { Selector } from 'testcafe';

const persistentId = { key: 'id' };

const element = Selector(() => {
    return document.querySelector(`[${persistentId.key}="submit-button"]`);
}, {
    dependencies: { persistentId },
});

fixture`Initialize selector with function on client side with dependencies`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Click on submit', async t => {
    await t.click(element);
});

TypeScript cannot find client function dependencies during compilation because TestCafe adds dependencies to the function’s scope at runtime. This can cause an error:

Error: TypeScript compilation failed.
Cannot find name 'dependencyFoo'.

To suppress the error, add the // @ts-ignore comment to the test file.

options.timeout

Type: Number

Time in milliseconds. If TestCafe fails to resolve the Selector query within this time limit, the test fails.

Default value: 3000. You can change the default value with the runner.run method or the --selector-timeout command line option.

options.visibilityCheck

Type: Boolean

If the visibilityCheck option is true, TestCafe imposes a visibility requirement on Selector targets.

The element is visible if:

  • The value of the element’s display property is not none
  • The value of the element’s visibility property is not hidden
  • The element has a non-zero width and height

Elements that meet the visibility criteria above may still be invisible to the user. The following factors do not influence the element’s visibility status:

  • The element’s z-index
  • The element’s opacity
  • The element’s position on the page

If the Selector query target does not become visible within the Selector timeout, the query fails.

The visibilityCheck option is not a filter function, and does not change the results of the query. TestCafe still counts invisible elements when you examine the count property:

<html>
  <body>
    <div>This div is visible</div>
    <div style="display:none">This div not is visible</div>
    <div style="visibility:hidden">This div not is visible either</div>
  </body>
</html>
const count = await Selector('div', { visibilityCheck: true }).count; // should return 3

To filter elements by visibility, use the following Selector methods: filterVisible, filterHidden.

Default value: false

Selector Methods

You can append Selector methods to the Selector constructor.

Selector methods perform additional actions with the return value of the main Selector query. Selector methods narrow, expand, or otherwise modify the selection of page elements.