• Stars
    star
    203
  • Rank 192,890 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 8 years ago
  • Updated 18 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

TestCafe selector extensions for React apps.

testcafe-react-selectors

This plugin provides selector extensions that make it easier to test ReactJS components with TestCafe. These extensions allow you to select page elements in a way that is native to React.

Install

$ npm install testcafe-react-selectors

Usage

Wait for application to be ready to run tests

To wait until the React's component tree is loaded, add the waitForReact method to fixture's beforeEach hook.

import { waitForReact } from 'testcafe-react-selectors';

fixture `App tests`
    .page('http://react-app-url')
    .beforeEach(async () => {
        await waitForReact();
    });

The default timeout for waitForReact is 10000 ms. You can specify a custom timeout value:

await waitForReact(5000);

If you need to call a selector from a Node.js callback, pass the current test controller as the second argument in the waitForReact function:

import { waitForReact } from 'testcafe-react-selectors';

fixture `App tests`
    .page('http://react-app-url')
    .beforeEach(async t => {
        await waitForReact(5000, t);
    });

The test controller will be assigned to the boundTestRun function's option. Otherwise, TestCafe would throw the following error: ClientFunction cannot implicitly resolve the test run in context of which it should be executed. See the TestCafe documentation for further details.

Creating selectors for ReactJS components

ReactSelector allows you to select page elements by the name of the component class or the nested component element.

Suppose you have the following JSX.

<TodoApp className="todo-app">
    <TodoInput />
    <TodoList>
        <TodoItem priority="High" key="HighPriority">Item 1</TodoItem>
        <TodoItem priority="Low" key="LowPriority">Item 2</TodoItem>
    </TodoList>

    <div className="items-count">Items count: <span>{this.state.itemCount}</span></div>
</TodoApp>

Selecting elements by the component name

To get a root DOM element for a component, pass the component name to the ReactSelector constructor.

import { ReactSelector } from 'testcafe-react-selectors';

const todoInput = ReactSelector('TodoInput');

Selecting nested components

To obtain a nested component or DOM element, you can use a combined selector or add DOM element's tag name.

import { ReactSelector } from 'testcafe-react-selectors';

const TodoList         = ReactSelector('TodoApp TodoList');
const itemsCountStatus = ReactSelector('TodoApp div');
const itemsCount       = ReactSelector('TodoApp div span');

Warning: if you specify a DOM element's tag name, React selectors search for the element among the component's children without looking into nested components. For instance, for the JSX above the ReactSelector('TodoApp div') selector will be equal to Selector('.todo-app > div').

Selecting components by the component key

To obtain a component by its key, use the withKey method.

import { ReactSelector } from 'testcafe-react-selectors';

const item = ReactSelector('TodoItem').withKey('HighPriority');

Selecting components by display name

You can select elements by the component's displayName.

For instance, consider the TodoList component whose displayName class property is specified as follows:

class TodoList extends React.Component {
  // ...
}

TodoList.displayName = 'TodoList';

In this instance, you can use todo-list-display-name to identify TodoList.

import { ReactSelector } from 'testcafe-react-selectors';

const list = ReactSelector('todo-list-display-name');

Selecting components by property values

React selectors allow you to select elements that have a specific property value. To do this, use the withProps method. You can pass the property and its value as two parameters or an object.

import { ReactSelector } from 'testcafe-react-selectors';

const item1 = ReactSelector('TodoApp').withProps('priority', 'High');
const item2 = ReactSelector('TodoApp').withProps({ priority: 'Low' });

You can also search for elements by multiple properties.

import { ReactSelector } from 'testcafe-react-selectors';

const element = ReactSelector('componentName').withProps({
    propName: 'value',
    anotherPropName: 'differentValue'
});
Properties whose values are objects

React selectors allow you to filter components by properties whose values are objects.

When the withProps function filters properties, it determines whether the objects (property values) are strictly or partially equal.

The following example illustrates strict and partial equality.

object1 = {
    field1: 1
}
object2 = {
    field1: 1
}
object3 = {
    field1: 1
    field2: 2
}
object4 = {
    field1: 3
    field2: 2
}
  • object1 strictly equals object2
  • object2 partially equals object3
  • object2 does not equal object4
  • object3 does not equal object4

Prior to version 3.0.0, withProps checked if objects are strictly equal when comparing them. Since 3.0.0, withProps checks for partial equality. To test objects for strict equality, specify the exactObjectMatch option.

The following example returns the componentName component because the objProp property values are strictly equal and exactObjectMatch is set to true.

// props = {
//   simpleProp: 'value',
//   objProp: {
//       field1: 'value',
//       field2: 'value'
//   }
// }

const element = ReactSelector('componentName').withProps({
    simpleProp: 'value',
    objProp: {
        field1: 'value',
        field2: 'value'
    }
}, { exactObjectMatch: true })

Note that the partial equality check works for objects of any depth.

// props = {
//     simpleProp: 'value',
//     objProp: {
//         field1: 'value',
//         field2: 'value',
//         nested1: {
//             someField: 'someValue',
//             nested2: {
//                 someField: 'someValue',
//                 nested3: {
//                     field: 'value',
//                     someField: 'someValue'
//                 }
//             }
//         }
//     }
// }


const element = ReactSelector('componentName').withProps({
    simpleProp: 'value',
    objProp: {
        field1: 'value',
        nested1: {
            nested2: {
                nested3: {
                    field: 'value'
                }
            }
        }
    }
}, { exactObjectMatch: false })

Searching for nested components

You can search for a desired subcomponent or DOM element among the component's children using the .findReact(element) method. The method takes the subcomponent name or tag name as a parameter.

Suppose you have the following JSX.

<TodoApp className="todo-app">
    <div>
        <TodoList>
            <TodoItem priority="High">Item 1</TodoItem>
            <TodoItem priority="Low">Item 2</TodoItem>
        </TodoList>
    </div>
</TodoApp>

The following sample demonstrates how to obtain the TodoItem subcomponent.

import { ReactSelector } from 'testcafe-react-selectors';

const component    = ReactSelector('TodoApp');
const div          = component.findReact('div');
const subComponent = div.findReact('TodoItem');

You can call the .findReact method in a chain, for example:

import { ReactSelector } from 'testcafe-react-selectors';

const subComponent = ReactSelector('TodoApp').findReact('div').findReact('TodoItem');

You can also combine .findReact with regular selectors and other) methods like .find or .withText, for example:

import { ReactSelector } from 'testcafe-react-selectors';

const subComponent = ReactSelector('TodoApp').find('div').findReact('TodoItem');

Combining with regular TestCafe selectors

Selectors returned by the ReactSelector constructor are recognized as TestCafe selectors. You can combine them with regular selectors and filter with .withText, .nth, .find and other functions. To search for elements within a component, you can use the following combined approach.

import { ReactSelector } from 'testcafe-react-selectors';

var itemsCount = ReactSelector('TodoApp').find('.items-count span');

Example

Let's use the API described above to add a task to a Todo list and check that the number of items changed.

import { ReactSelector } from 'testcafe-react-selectors';

fixture `TODO list test`
	.page('http://localhost:1337');

test('Add new task', async t => {
    const todoTextInput = ReactSelector('TodoInput');
    const todoItem      = ReactSelector('TodoList TodoItem');

    await t
        .typeText(todoTextInput, 'My Item')
        .pressKey('enter')
        .expect(todoItem.count).eql(3);
});

Obtaining component's props and state

As an alternative to testcafe snapshot properties, you can obtain state, props or key of a ReactJS component.

To obtain component's properties, state and key, use the React selector's .getReact() method.

The .getReact() method returns a client function. This function resolves to an object that contains component's properties (excluding properties of its children), state and key.

const reactComponent      = ReactSelector('MyComponent');
const reactComponentState = await reactComponent.getReact();

// >> reactComponentState
//
// {
//     props:    <component_props>,
//     state:    <component_state>,
//     key:      <component_key>
// }

The returned client function can be passed to assertions activating the Smart Assertion Query mechanism.

Example

import { ReactSelector } from 'testcafe-react-selectors';

fixture `TODO list test`
	.page('http://localhost:1337');

test('Check list item', async t => {
    const el         = ReactSelector('TodoList');
    const component  = await el.getReact();

    await t.expect(component.props.priority).eql('High');
    await t.expect(component.state.isActive).eql(false);
    await t.expect(component.key).eql('componentID');
});

As an alternative, the .getReact() method can take a function that returns the required property, state or key. This function acts as a filter. Its argument is an object returned by .getReact(), i.e. { props: ..., state: ..., key: ...}.

ReactSelector('Component').getReact(({ props, state, key }) => {...})

Example

import { ReactSelector } from 'testcafe-react-selectors';

fixture `TODO list test`
    .page('http://localhost:1337');

test('Check list item', async t => {
    const el = ReactSelector('TodoList');

    await t
        .expect(el.getReact(({ props }) => props.priority)).eql('High')
        .expect(el.getReact(({ state }) => state.isActive)).eql(false)
        .expect(el.getReact(({ key }) => key)).eql('componentID');
});

The .getReact() method can be called for the ReactSelector or the snapshot this selector returns.

TypeScript Generic Selector

Use the generic ReactComponent type to create scalable selectors in TypeScript.

Pass the props object as the type argument to ReactComponent to introduce a type for a specific component.

type TodoItem = ReactComponent<{ id: string }>;

You can then pass the created TodoItem type to the withProps and getReact generic methods.

const component  = ReactSelector('TodoItem');
type TodoItem    = ReactComponent<{ id: string }>;

const item1  = component.withProps<TodoItem>('id', 'tdi-1');
const itemId = component.getReact<TodoItem>(({ props }) => props.id);

Example

import { ReactSelector, ReactComponent } from 'testcafe-react-selectors';

fixture`typescript support`
    .page('http://react-page-example.com')

test('ReactComponent', async t => {
    const todoList         = ReactSelector('TodoList');
    type TodoListComponent = ReactComponent<{ id: string }>;

    const todoListId = todoList.getReact<TodoListComponent>(({ props }) => props.id);

    await t.expect(todoListId).eql('ul-item');
});

Composite Types in Props and State

If a component's props and state include other composite types, you can create your own type definitions for them. Then pass these definitions to ReactComponent as type arguments.

The following example shows custom Props and State type definitions. The State type uses another composite type - Option.

import { ReactComponent } from 'testcafe-react-selectors';

interface Props {
    id: string;
    text: string;
}

interface Option {
    id: number;
    title: string;
    description: string;
}

interface State {
    optionsCount: number;
    options: Option[];
}

export type OptionReactComponent = ReactComponent<Props, State>;

Limitations

  • testcafe-react-selectors support ReactJS starting with version 16. To check if a component can be found, use the react-dev-tools extension.

  • Search for a component starts from the root React component, so selectors like ReactSelector('body MyComponent') will return null.

  • ReactSelectors need class names to select components on the page. Code minification usually does not keep the original class names. So you should either use non-minified code or configure the minificator to keep class names.

    For babel-minify, add the following options to the configuration:

    { keepClassName: true, keepFnName: true }

    In UglifyJS, use the following configuration:

    {
        compress: {
            keep_fnames: true
        },
    
        mangle: {
            keep_fnames: true
        }
    }

More Repositories

1

testcafe

A Node.js tool to automate end-to-end web testing.
JavaScript
9,821
star
2

devextreme-reactive

Business React components for Bootstrap and Material-UI
TypeScript
2,077
star
3

DevExtreme

HTML5 JavaScript Component Suite for Responsive Web Development
JavaScript
1,807
star
4

devextreme-angular

Angular UI and data visualization components
TypeScript
560
star
5

Blazor

DevExpress UI for Blazor
C#
386
star
6

AjaxControlToolkit

The ASP.NET AJAX Control Toolkit is a classic set of ASP.NET WebForms extensions.
JavaScript
287
star
7

devextreme-vue

Vue UI and data visualization components
TypeScript
267
star
8

DevExpress.Mvvm.Free

DevExpress MVVM Framework is a set of components helping to work in the Model-View-ViewModel pattern in WPF.
C#
221
star
9

testcafe-hammerhead

A powerful web-proxy used as a core for the TestCafe testing framework. 🔨 😃
JavaScript
171
star
10

XPO

DevExpress eXpress Persistent Objects (XPO) ORM for .NET Framework / .NET Core / .NET Standard 2.0
JavaScript
162
star
11

devextreme-react

React UI and data visualization components
JavaScript
160
star
12

DevExtreme.AspNet.Data

DevExtreme data layer extension for ASP.NET
C#
137
star
13

devextreme-angular-template

Responsive Application Layout Templates​ based on DevExtreme Angular Components
CSS
119
star
14

testcafe-live

A tool for rapid test development with TestCafe
JavaScript
118
star
15

obsolete-devextreme-examples

A set of sample applications that will help you to get started.
TypeScript
109
star
16

testcafe-vue-selectors

TestCafe selector extensions for Vue.js apps.
JavaScript
103
star
17

testcafe-browser-provider-browserstack

This is the BrowserStack browser provider plugin for TestCafe.
JavaScript
86
star
18

devextreme-ui-template-gallery

DevExtreme UI Template Gallery
TypeScript
85
star
19

bootstrap-aspnetcore-starter

This repository is obsolete. See README for details.
HTML
81
star
20

web-dashboard-demo

The following application contains the DevExpress Dashboard Component for Angular. The client side is hosted on the GitHub Pages and gets data from the server side that hosts on DevExpress.com.
TypeScript
70
star
21

Logify.Alert.Clients

Logify Alert - crash reporting / exception handling service
C#
66
star
22

dashboard-extension-online-map-item

â›” DEPRECATED. This project was moved to a new repository. Visit https://github.com/DevExpress/dashboard-extensions to find an updated version.
TypeScript
63
star
23

dashboard-extension-webpage-item

â›” DEPRECATED. This project was moved to a new repository. Visit https://github.com/DevExpress/dashboard-extensions to find an updated version.
TypeScript
62
star
24

dashboard-extension-funnel-d3-item

â›” DEPRECATED. This project was moved to a new repository. Visit https://github.com/DevExpress/dashboard-extensions to find an updated version.
JavaScript
61
star
25

bootstrap-themes

Themes for Bootstrap
HTML
59
star
26

blazor-training-samples

This repository is obsolete. See README for details.
HTML
55
star
27

dotnet-eud

DevExpress .NET Controls Documentation for End Users
JavaScript
54
star
28

testcafe-examples

Ready-to-run examples for TestCafe
JavaScript
50
star
29

devextreme-cli

A command-line interface for DevExtreme
TypeScript
50
star
30

DevExtreme-PHP-Data

DevExtreme data layer extension for PHP
PHP
49
star
31

testcafe-browser-provider-electron

This is the Electron browser provider plugin for TestCafe.
JavaScript
49
star
32

dashboard-extension-parameter-item

â›” DEPRECATED. This project was moved to a new repository. Visit https://github.com/DevExpress/dashboard-extensions to find an updated version.
JavaScript
48
star
33

aspnet-security-bestpractices

A project illustrating security best practices for DevExpress ASP.NET controls. See the README for detailed information.
C#
47
star
34

devextreme-vue-template

Responsive Application Layout Templates​ based on DevExtreme Vue Components
CSS
46
star
35

devextreme-documentation

DevExtreme documentation
JavaScript
44
star
36

aspnet-office-solutions

A set of solutions for building scalable web applications containing DevExpress ASP.NET Spreadsheet and Rich Text Editor controls.
C#
44
star
37

dashboard-extension-dashboard-panel

â›” DEPRECATED. This project was moved to a new repository. Visit https://github.com/DevExpress/dashboard-extensions to find an updated version.
TypeScript
43
star
38

devextreme-demos

DevExtreme technical demos
C#
42
star
39

DevExpress.Mvvm.CodeGenerators

DevExpress ViewModel generator
C#
41
star
40

bower-devextreme

This repo is for distribution of DevExtreme Complete product.
CSS
40
star
41

netcore-winforms-demos

This repository contains the Outlook Inspired and Stock Market Trader demo applications that support .Net Core 3.
C#
39
star
42

testcafe-action

TestCafe test runner for GitHub Actions
JavaScript
37
star
43

DevExtreme.AspNet.TagHelpers

[OBSOLETE] See https://js.devexpress.com/Overview/Mvc/
C#
37
star
44

dashboard-extension-simple-table

â›” DEPRECATED. This project was moved to a new repository. Visit https://github.com/DevExpress/dashboard-extensions to find an updated version.
JavaScript
37
star
45

devextreme-react-template

Responsive Application Layout Templates​ based on DevExtreme React Components
CSS
33
star
46

testcafe-angular-selectors

TestCafe selector extensions for Angular apps.
JavaScript
32
star
47

testcafe-browser-provider-saucelabs

This is the Sauce Labs browser provider plugin for TestCafe.
JavaScript
31
star
48

testcafe-browser-tools

Browser manipulation utils for TestCafe.
C++
30
star
49

wpf-themedesigner-app

This is a publish-only repository and all pull requests are ignored. Please follow the Support page for any of your improvements.
29
star
50

golfclub

GolfClub: Angular and DevExtreme sample application
TypeScript
24
star
51

Reporting.Import

An import tool designed to convert third party reports into an internal format supported by DevExpress Reports
C#
24
star
52

devextreme-schematics

Schematics for DevExtreme Angular applications.
TypeScript
20
star
53

ThemeBuilder

A tool for creating custom DevExtreme themes
TypeScript
20
star
54

dashboard-extensions

This repository is obsolete. See README for details.
TypeScript
18
star
55

dataprocessingapi-mvp-example

DevExpress Data Processing API is a prototype (MVP) of a new product and is therefore not yet a part of the DevExpress product line. The prototype supports only v21.2 and is not production-ready. Use it at your own risk.
C#
18
star
56

BigQueryProvider

The DevExpress BigQueryProvider driver is no longer maintained and supported. Use Google's official ODBC driver to obtain BigQuery data in your .NET apps.
C#
15
star
57

DevExtreme.AspNet.Mvc-Demos-NETCore

[OBSOLETE] See https://js.devexpress.com/Overview/Mvc/
C#
15
star
58

OBSOLETE_EF-Core-Security

Security system for Entity Framework Core with demos
CSS
15
star
59

winui-demos

DevExpress WinUI 3 demos that show how to use DevExpress WinUI components and tools, including the Data Grid, Reporting, Scheduler, Charting, and Data Editors.
C#
14
star
60

angular-testcafe

Angular builder to run testcafe tests
TypeScript
14
star
61

match-url-wildcard

Module to match url by pattern
JavaScript
13
star
62

device-specs

JavaScript
13
star
63

DevExtreme-Intl

Integrates ECMAScript Internationalization API with DevExtreme
JavaScript
13
star
64

dx-election

DX Election: Angular and DevExtreme sample application
TypeScript
13
star
65

XAF-Blazor-Kubernetes-example

This example shows how to deploy XAF Blazor application to the Kubernetes cluster and to enable horizontal autoscaling
C#
13
star
66

SalesViewer

TypeScript
12
star
67

netcore-wpf-demos

Please visit https://www.devexpress.com/dotnet-core-3 to download the most recent version of the DevExpress .NET Core installer (contains shipping versions of all DevExpress .NET Core demos).
12
star
68

gulp-testcafe

Run TestCafe tests using Gulp.
JavaScript
11
star
69

testcafe-studio-docs

[deprecated] Documentation for TestCafe Studio
11
star
70

bower-xtrareports-js

JavaScript
10
star
71

testcafe-reporter-json

This is the JSON reporter plugin for TestCafe.
JavaScript
9
star
72

testcafe-reporter-xunit

This is the xUnit reporter plugin for TestCafe.
JavaScript
9
star
73

gimp-dx-screenshot

GIMP Scripts for Screenshot Processing
Scheme
7
star
74

winforms-training-samples

C#
7
star
75

generator-testcafe-reporter

Scaffold out a TestCafe reporter.
JavaScript
7
star
76

testcafe-gh-page-assets

This repository contains assets used in the TestCafe GitHub page.
SCSS
6
star
77

testcafe-aurelia-selectors

TesCafe selector extensions for Aurelia apps.
JavaScript
6
star
78

testcafe-reporter-spec

This is the Spec reporter plugin for TestCafe.
JavaScript
6
star
79

DevExtreme.AspNet.Data.NgHttpClientSample

Refer to https://github.com/DevExpress/DevExtreme.AspNet.Data/issues/311
TypeScript
6
star
80

bower-devextreme-web

[OBSOLETE] See https://github.com/DevExpress/bower-devextreme
JavaScript
5
star
81

TestCafe-Scheduler

Schedule TestCafe testing tasks
JavaScript
5
star
82

testcafe-legacy-api

Legacy API support for TestCafe.
JavaScript
5
star
83

testcafe-reporter-list

This is the List reporter plugin for TestCafe.
JavaScript
5
star
84

xaf-blazor-app-load-testing-example

XAF Blazor Server application load testing example
C#
5
star
85

TestCafe-BrowserStack

Add remote workers from the BrowserStack web service to the TestCafe.
JavaScript
5
star
86

testcafe-browser-provider-phantomjs

This is the PhantomJS browser provider plugin for TestCafe.
JavaScript
5
star
87

devextreme-renovation

TypeScript
5
star
88

aspnet-documentmanagement-bestpractices

A project illustrating best practices of using DevExpress ASP.NET control to create the responsive document management application. See the README for detailed information.
C#
5
star
89

saucelabs-connector

JavaScript
4
star
90

wpf-training-samples

C#
4
star
91

TODO-App-via-DevExpress-MVVM

Simple TODO Application powered by DevExpress WinForms MVVM.
Visual Basic .NET
4
star
92

DevExtreme-Data-Parse

[OBSOLETE] See https://js.devexpress.com/Documentation/Guide/Data_Layer/Data_Layer/
JavaScript
4
star
93

create-testcafe

JavaScript
3
star
94

vscode-rushsnippets

Templates for TypeScript, React and Redux projects that help you write your code faster
3
star
95

TestCafe-RPC

RPC library for the TestCafé.
JavaScript
3
star
96

TestCafe-Wrappers

TestCafe wrappers are a set of JavaScript classes that help you work with the DevExpress ASP.NET controls in TestCafe
JavaScript
3
star
97

testcafe-reporter-minimal

This is the Minimal reporter plugin for TestCafe.
JavaScript
3
star
98

DevExtremeAddon

[OBSOLETE] This plugin setups the CordovaView in the Windows Phone application.
C#
2
star
99

TestCafe-RemoteWorkers

How to make the Continuous Integration system work with remote workers with a single TestCafe instance
JavaScript
2
star
100

DevExtreme-Data-JayData

[OBSOLETE] See https://js.devexpress.com/Documentation/Guide/Data_Layer/Data_Layer/
JavaScript
2
star