Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Modern Web Testing with TestCafe

You're reading from   Modern Web Testing with TestCafe Get to grips with end-to-end web testing with TestCafe and JavaScript

Arrow left icon
Product type Paperback
Published in Sep 2020
Publisher Packt
ISBN-13 9781800200951
Length 168 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Dmytro Shpakovskyi Dmytro Shpakovskyi
Author Profile Icon Dmytro Shpakovskyi
Dmytro Shpakovskyi
Arrow right icon
View More author details
Toc

Table of Contents (9) Chapters Close

Preface 1. Chapter 1: Why TestCafe? 2. Chapter 2: Exploring TestCafe Under the Hood FREE CHAPTER 3. Chapter 3: Setting Up the Environment 4. Chapter 4: Building a Test Suite with TestCafe 5. Chapter 5: Improving the Tests 6. Chapter 6: Refactoring with PageObjects 7. Chapter 7: Findings from TestCafe 8. Other Books You May Enjoy

Learning about the TestCafe API

Since the server-side code runs in Node.js, tests should be written in JavaScript (TypeScript and CoffeeScript are also supported, but eventually, everything should be transpiled into JavaScript).

TestCafe utilizes a minimalistic API that provides less than a few dozen methods, which are then transformed into user actions on the page. As our tests will be using the TestCafe API methods to interact with the pages, let's review the main interaction groups supported in TestCafe:

  • Elements selection.
  • Actions.
  • Assertions.
  • User roles.

Let's discover each of these interactions in more detail.

Elements selection

TestCafe utilizes an advanced mechanism with built-in waiting to locate target elements for an action or assertion. To perform an action (such as click, hover, type, and so on) or to make an assertion, you should first identify the target page element. This is as easy as specifying a standard CSS selector. For more complex situations, you can chain methods (such as, for example, getting an element by class name, then getting its second child, and then finally, getting its third sibling). Selector strings should be passed inside chainable Selector constructors to create a selector.

For example, you can click on a button with the button-test class, as follows:

const { Selector } = require('testcafe');const buttonTest = Selector('.button-test');

For more complex situations, you can traverse the DOM tree by chaining selectors:

const { Selector } = require('testcafe');const linkTest = Selector('#block-test')    .child('a')    .withAttribute('href', 'https://test-site.com/main.html')    .withText('Second link');

What this chain of selectors does is the following:

  1. Selects an element with the block-test id.
  2. Selects its child elements.
  3. Filters them by the a tag.
  4. Selects elements with the href attribute that includes https://test-site.com/main.html.
  5. Selects elements that include the Second link text.

    Note

    If a selector matches several elements, the subsequent methods return results for all the elements that were matched.

TestCafe provides a number of methods that search for elements relative to the selected element (keep in mind that all of these methods should be prepended with Selector(cssSelector)). Most of these methods accept index as an argument, which should be a zero-based number (0 will be the closest relative element in the set). If the number is negative, the index is counted from the end of the matched set. Here are the methods:

Now, let's look at the methods that filter elements from the selector. The same as before, all of these methods should be prepended with Selector(cssSelector). Here are the methods:

When a selector is executed, TestCafe will be waiting for the target node to appear on the page until the selector timeout expires. You can specify the timeout (in milliseconds) in the following cases:

During the timeout, the selector is rerun until it returns a DOM element or the timeout is surpassed. If TestCafe can't find the corresponding node in the DOM, the test is marked as failed.

Actions

The TestCafe API provides a set of action methods to interact with the page (such as click, type, select text, hover, and so on). You can call them one after another in a chained fashion. All of these methods should be prepended with t as they are the methods of the test controller object (https://devexpress.github.io/testcafe/documentation/reference/test-api/testcontroller/). Also, selector can be a string, selector, DOM node, function, or Promise; and optionally, you can use options, which is an object with a set of options containing supplementary parameters for the action (unless otherwise specified). Here are all the main action methods:

Assertions

TestCafe allows you to verify elements, page properties, and parameters (equals, contains, greater, match, and so on). To write assertions, use the test controller's t.expect method, followed by an assertion method that accepts an expected value and optional arguments; message is the assertion message string that shows up in the report if the test fails and options is an object with a set of options containing supplementary parameters for the assertion. Here are all the assertion methods available in TestCafe out of the box:

User roles

TestCafe has a built-in user role mechanism that emulates user actions for logging in to a website. It also saves the logged-in state of each user in a separate role that can be reused later on in any part of your tests to switch between user accounts. This approach gives access to some unique features:

  • Login actions are not duplicated upon switching to a previously used role during the same session. So, for example, if you activate a role in the beforeEach hook, the login actions will run only once before the first test. All further tests will just reuse the existing authentication data.
  • When you switch roles, the browser automatically navigates back to the page where the switch happened, so there is no need to additionally open any URLs for a new role (this behavior can be disabled if required).
  • If during a test you log in to several websites, authentication data from cookies and browser storage is saved in the active role. When switching back to this role in the same test, you will be logged in to all the websites automatically.
  • An anonymous built-in role that logs you out of all accounts.

Let's have a look at a practical example of creating and using roles.

To create and initialize a role, we will need to use a Role constructor. Then, the login page URL and actions needed to log in should be passed to Role. This is shown in the following code block:

const { Role, Selector } = require('testcafe');const regularUser = Role('https://test-site.com/login', async (t) => {    await t.typeText('.login', 'TestUser')        .typeText('.password', 'testuserpass')        .click('#log-in');});const admin = Role('https://test-site.com/login', async (t) => {    await t.typeText('.login', 'TestAdmin')        .typeText('.password', 'testadminpass')        .click('#log-in');});const linkLoggedInUser = Selector('.link-logged-in-user');const linkLoggedInAdmin = Selector('.link-logged-in-admin');fixture('My first test Fixture').page('https://test-site.com');test('Test login with three users', async (t) => {    await t.useRole(regularUser)        .expect(linkLoggedInUser.exists).ok()        .useRole(admin)        .expect(linkLoggedInUser.exists).notOk()        .expect(linkLoggedInAdmin.exists).ok()        .useRole(Role.anonymous())        .expect(linkLoggedInUser.exists).notOk()        .expect(linkLoggedInAdmin.exists).notOk();});

After you create all the required roles, you can switch between them anytime; roles are shared across tests and fixtures. Roles can even be created in a separate file and then used in any test fixture that references (requires or imports) this file.

To sum up, in this section, we reviewed the TestCafe API and the main methods that it provides. We also learned how to select elements, conduct assertions, and utilize user roles to switch between different accounts. Now, let's take a look at how custom client-side code can be executed in TestCafe to give us even more control over the browser.

You have been reading a chapter from
Modern Web Testing with TestCafe
Published in: Sep 2020
Publisher: Packt
ISBN-13: 9781800200951
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime