Assertions

You can use assertions to check if the tested webpage's state matches the expected state.

TestCafe provides a comprehensive set of assertions that are based on the Behavior Driven Development style (BDD-style). See Assertion API for more information.

This topic consists of the following sections:

Assertion Structure

To construct assertions, use the test controller's expect method.

This method accepts the actual value. You can pass a value, a Selector's DOM node state property or a client function promise. TestCafe automatically waits for node state properties to obtain a value and for client functions to execute. See Smart Assertion Query Mechanism for details.

You cannot pass a regular promise to the expect method unless the options.allowUnawaitedPromise option is enabled.

Next is an assertion method that accepts an expected value and, optionally, other arguments.

For instance, the deep equality assertion has the following structure:

await t.expect( actual ).eql( expected, message, options );

The sample below demonstrates how to use assertions:

import { Selector } from 'testcafe';


fixture `Example page`
   .page `http://devexpress.github.io/testcafe/example/`;


test('Check property of element', async t => {
   const developerNameInput = Selector('#developer-name');

   await t
       .expect(developerNameInput.value).eql('', 'input is empty')
       .typeText(developerNameInput, 'Peter Parker')
       .expect(developerNameInput.value).contains('Peter', 'input contains text "Peter"');
});

Smart Assertion Query Mechanism

You can perform the required assertions immediately after test action is executed in synchronous functional testing.

Synchronous Functional Testing

Functional tests are asynchronous on the web. This means that we cannot get the expected changes immediately after an end-user's actions. For example, it can take time for the tested web page to send a request to the server for the required data, or an end-user's action launches an animation after which the web page reaches its final state. All these intervals cannot be pre-calculated because they depend on various factors: computer performance, network connection speed, etc. In this case, if we perform assertions immediately after the test action finished, we can get an inconclusive result.

Asynchronous Functional Testing

An additional timeout is usually added when performing asynchronous functional tests.

Asynchronous Functional Testing with Extra Waiting

To stabilize such tests, you need to add a timeout that enables the required changes to be applied successfully. Note that adding such timeouts can increase the test's duration.

TestCafe uses the smart assertion query mechanism if the assertion receives a Selector's DOM node state property or client function promise as an actual value: if an assertion did not pass, the test does not fail immediately. The assertion retries to pass multiple times, and each time it requests the actual property value. The test fails if the assertion could not complete successfully within a timeout:

TestCafe Smart Assertion Query Mechanism

Example:

The following web page is an example:

<div id="btn"></div>
<script>
var btn = document.getElementById('btn');

btn.addEventListener(function() {
    window.setTimeout(function() {
        btn.innerText = 'Loading...';
    }, 100);
});
</script>

Test code for this page can be as follows.

test('Button click', async t => {
    const btn = Selector('#btn');

    await t
        .click(btn)
        // A regular assertion fails immediately, but TestCafe retries to run DOM state
        // assertions many times within the timeout until this assertion passes successfully.
        // The default timeout is 3000 ms.
        .expect(btn.textContent).contains('Loading...');
});

The approach described above allows you to create stable tests with a fast run-time that do not contain random errors.

You can specify the assertion query timeout in test code by using the options.timeout option. To set the timeout when launching tests, pass the timeout value to the runner.run method if you use an API or specify the assertion-timeout option if you run TestCafe from the command line.

Assertion options

options.timeout

Type: Number

The time (in milliseconds) an assertion can take to pass before the test fails if a selector property or client function promise was used in assertion.

Default value: The timeout is specified using the runner.run API method or the assertion-timeout command line option.

await t.expect(Selector('#elementId').innerText).eql('text', 'check element text', { timeout: 500 });

In addition to built-in assertions, you also can use assertions from Node's built-in assert module or 3rd-party library (for example chai). In this case, specify the time required to complete asynchronous actions using the t.wait(timeout) method.

options.allowUnawaitedPromise

By default, only promises the selectors and client functions return can be passed as the assertion's actual value. If you pass a regular unawaited promise, TestCafe throws an error.

If you need to assert a regular promise, set the allowUnawaitedPromise option to true.

await t.expect(doSomethingAsync()).ok('check that a promise is returned', { allowUnawaitedPromise: true });