Bored of Selenium? Try out TestCafe!

Adrian Benko
TestAutonation
Published in
6 min readJan 9, 2022

If you think, that WebdriverIO is the only framework to test web apps, think again. When you start with a new testing framework for the web, it usually requires WebDriver or Selenium as a dependency, in some cases you also need to install (or at least update) JDK. Once you start the framework implementation, you might also decide to integrate tools such as test reporting tools and cloud support, into it, so you start to research which package is best for your needs. If you want to try out something new and you don’t want to search exhaustively for 3rd party packages to integrate, TestCafe might be your best friend.

Introduction

Although it’s not as popular as WebDriverIO, TestCafe is a relatively new, open-source, Node.js-based e2e testing framework. It’s an excellent alternative to Selenium-based tools since it injects itself into the website as JS scripts, so it’s more stable and faster. This allows TestCafe to run on any browser, including mobile devices and cloud services as well. It doesn’t need Selenium to start your browser window, execute the tests in it and provide useful test reports after the execution. I know it’s not very common, but it just works right out of the box.

Installation of TestCafe

Since TestCafe is a Node.js based framework, it requires installation on your machine. If you have Node.js already installed, just type in “ npm install -g testcafe “ into your terminal/shell, and that’s it.

First Tests

DevExpress , authors of this framework created a nice , which can be used for our tests as well. It contains all the necessary elements for our tests (input boxes, checkboxes, radio buttons, select boxes, etc.)

Similarly to other BDD frameworks, tests in TestCafe start with the keyword, which should contain a very brief description of your feature/test. Also, you need to append the page URL to the fixture, so it opens it before the main tests are executed.

Let’s say, that we want to open the DEMO page, type in our name to the input box and then click on the Submit button. How shall we do it?

import { Selector } from 'testcafe';

fixture `Check DEMO page`
.page `https://devexpress.github.io/testcafe/example`;

test('My first test for the INPUT box', async t => {
await t
.typeText('#developer-name', 'Adrian')
.click('#submit-button');
});

Once your test is written, would be nice to execute it as well, right? Hold your horses for a while! Since we don’t use configuration files, we need to specify somehow which browser should be used for the test execution. Also, we need to make sure, that the already installed browsers are visible to TestCafe. Fortunately, this can be done easily, just type-in the testcafe -list-browsers command to your Terminal to see the available browsers:

testcafe testcafe --list-browsers firefox chrome-canary chrome opera safari

Let’s say, that we want to execute our tests in chrome, so we need to type in the following command:

testcafe testcafe chrome test.js Running tests in: - Chrome 66.0.3359 / Mac OS X 10.13.4 Check DEMO page ✓ My first test for the INPUT box1 passed (2s)

That was an easy task, so let’s add some complexity to it.

When you type in your name to the input field and hit the Submit button, you’re forwarded to the http://devexpress.github.io/testcafe/example/thank-you.html page, which says “ “. To verify, that the text displays the correct name, we’ll extend our test with an assertion command. But first, we’ll introduce the Selector object, which will store the locator to this text:

import { Selector } from 'testcafe';

fixture `Check DEMO page`
.page `https://devexpress.github.io/testcafe/example`;

const articleHeader = Selector('#article-header');
const myName = 'Adrian';

test('My first test for the INPUT box', async t => {
await t
.typeText('#developer-name', myName)
.click('#submit-button')
.expect(articleHeader.innerText).eql('Thank you, '+ myName +'!');
});

Let’s execute it and check the results:

testcafe testcafe chrome test.js Running tests in: - Chrome 66.0.3359 / Mac OS X 10.13.4 Check DEMO page ✓ My first test for the INPUT box1 passed (2s)

Ok, that was fast. To make sure, that our test works correctly, let’s change the text in the expect command to something else:

const notMyName = 'Paul';
//...
.expect(articleHeader.innerText).eql('Thank you, '+ notMyName +'!');

and run our test:

testcafe testcafe chrome test.js Running tests in: - Chrome 66.0.3359 / Mac OS X 10.13.4 
Check DEMO page ✖ My first test for the INPUT box
1) AssertionError: expected 'Thank you, Adrian!' to deeply equal 'Thanks, Adrian!'
Browser: Chrome 66.0.3359 / Mac OS X 10.13.4
7 |
8 |test('My first test for the INPUT box', async t => {
9 | await t
10 | .typeText('#developer-name', myName)
11 | .click('#submit-button') >
12 | .expect(articleHeader.innerText).eql('Thanks, '+ myName +'!'); 13 |}); at <anonymous> (/Users/adrianbenko/Development/testcafe/test.js:12:50) at test (/Users/adrianbenko/Development/testcafe/test.js:8:1)
1/1 failed (5s)

As you can see, the assertions seem to work fine; our test fulfills its purpose.

DevExpress recommends using Page Objects in TestCafe

Authors of the framework highly recommend to use Page Objects in our tests, so we make our tests and pages reusable, and we reduce the maintenance costs of our project. If you’ve already created some page objects, this should be easy for you.

Let’s start with our test. As you can see from the , our test uses three web elements:

  • Input field, with id=developer-name
  • Submit button with id=submit-button
  • And the h1 tag for the text, with id=article-header

Hence we need to create our page object with these three web elements:

import { Selector } from 'testcafe';
export default class Page {
constructor () {
this.nameInput = Selector('#developer-name');
this.submitButton = Selector('#submit-button');
this.articleHeader = Selector('#article-header');
}
}

Save it under the pageObject.js name, so we can import it to our test by using the standard import for JS files:

import Page from './pageObject';
fixture `My first fixture`
.page `https://devexpress.github.io/testcafe/example`;

const page = new Page();
const myName = 'Adrian';

test('My first test for the INPUT box', async t => {
await t
.typeText(page.nameInput, myName)
.click(page.submitButton)
.expect(page.articleHeader.innerText).eql('Thank you, ' + myName + '!');
});

Run your tests on Sauce Labs!

To be able to run our tests on SauceLabs Cloud, first, we need to set the SAUCE_USERNAME and SAUCE_ACCESS_KEY variables, as it is recommended by the SauceLabs guys here: https://wiki.saucelabs.com/display/DOCS/Best+Practice%3A+Use+Environment+Variables+for+Authentication+Credentials

Unfortunately, the SauceLabs integration is not installed by default, so we need to install it manually via the following command:

npm install -g testcafe-browser-provider-saucelabs

Before we execute our tests on SauceLab, we can get all the available browser and OS combinations from them, so we can pick up the best platform for our test:

testcafe testcafe -b saucelabs 
"saucelabs:MicrosoftEdge@16.16299:Windows 10"
"saucelabs:MicrosoftEdge@14.14393:Windows 10"
"saucelabs:Chrome@dev:Windows 10"
"saucelabs:Chrome@beta:Windows 10"
"saucelabs:Chrome@66.0:Windows 10"
"saucelabs:Chrome@65.0:Windows 10"
"saucelabs:Chrome@64.0:Windows 10"
"saucelabs:Chrome@55.0:Windows 10"

As you can see, list of the supported devices is really long, so you’ll find your browser/OS combination there for sure.

Just to try out different platforms, we’ll execute our tests on Windows 10 for now:

testcafe testcafe "saucelabs:Chrome@beta:Windows 10" test.js
Running tests in:
- Chrome 67.0.3396 / Windows 10.0.0 (https://saucelabs.com/tests/c0e7b90ebc284d4c90aef6fed3c947db)

My first fixture
✓ My first test for the INPUT box

1 passed (7s)

Once the tests are passed to the SauceLabs Cloud, you can check out the on their boards to see the progress:

Active Tunel

It’s not a surprise, that our test passed on the SauceLabs as well 🙂

Test Results

Interested in SauceLabs? You should be! Will soon write more articles using this great cloud service so keep checking us!

Conclusion

TestCafe is a very powerful, relatively new framework, which is definitely worth trying. In our next post we’ll try out

  • the headless mode,
  • the concurrent execution of the tests
  • and we’ll take a more in-depth look at the reporting part as well. Stay tuned 😉

If you want to read and learn more about TestCafe, or you have some questions, don’t hesitate to Contact us!

PS.

You can download the whole project from our GitHub repository.

Originally published at https://testautonation.com.

--

--

Adrian Benko
TestAutonation

Adrian spent 10+ years as a QA, he's passionate about education, and he used to teach at universities in Budapest about Test Automation.