TestCafe v0.14.0 Released

Authentication via user roles, client-side debugging and numerous bug fixes.

⚙ Authentication via user roles (#243) #

Many test scenarios involve the activity of more than one user. TestCafe addresses these scenarios by providing a convenient way to isolate authentication test actions and apply them easily whenever you need to switch the user account.

A piece of logic that logs in a particular user is called a role. It is a good practice to create a role for each user account participating in your test.

Create roles via the Role constructor. You can keep them in a separate helper file.

helper.js

import { Role } from ' testcafe ' ; export var regularAccUser = Role ( ' http://example.com/login ' , async t => { await t . typeText ( ' #login ' , ' TestUser ' ) . typeText ( ' #password ' , ' testpass ' ) . click ( ' #sign-in ' ); }); export var facebookAccUser = Role ( ' http://example.com/login ' , async t => { await t . click ( ' #sign-in-with-facebook ' ) . typeText ( ' #email ' , ' testuser@mycompany.com ' ) . typeText ( ' #pass ' , ' testpass ' ) . click ( ' #submit ' ); }); export var admin = Role ( ' http://example.com/login ' , async t => { await t . typeText ( ' #login ' , ' Admin ' ) . typeText ( ' #password ' , ' adminpass ' ) . click ( ' #sign-in ' ); });

In test code, use the t.useRole method to switch between roles.

test.js

import { regularAccUser , admin } from ' ./helper ' ; import { Selector } from ' testcafe ' ; const entry = Selector ( ' #entry ' ); const removeButton = Selector ( ' #remove-entry ' ); fixture `My Fixture` . page `http://example.com` ; test ( ' test that involves two users ' , async t => { await t . useRole ( regularAccUser ) . expect ( entry . exists ). ok () . expect ( removeButton . visible ). notOk () . useRole ( admin ) . expect ( removeButton . visible ). ok () . click ( removeButton ) . expect ( entry . exists ). notOk () });

To learn more, see User Roles.

We have released the BrowserStack browser provider plugin.

Install this plugin from npm .

npm install testcafe-browser-provider-browserstack

And save the BrowserStack username and access key to environment variables BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY .

Now you can run tests on any virtual machine available on BrowserStack.

testcafe "browserstack:Chrome@53.0:Windows 10" "path/to/test/file.js"

We have added a new t.debug method to debug test behavior on the client.

When test execution reaches t.debug , it pauses so that you can open browser's developer tools and check the web page state, DOM elements location, their CSS styles.

fixture `My fixture` . page `https://devexpress.github.io/testcafe/example` ; test ( ' My test ' , async t => { await t . debug () . setNativeDialogHandler (() => true ) . click ( ' #populate ' ) . click ( ' #submit-button ' ); });

In the footer, you'll find buttons that allow you to continue test execution or step to the next test action.

TestCafe logs points in code where the debugger stopped.

You can now run tests against local webpages. To do this, specify a URL with the file:// scheme or a relative path when calling the page function.

fixture `MyFixture` . page `file:///user/my-website/index.html` ;

fixture `MyFixture` . page `../my-project/index.html` ;

You can also navigate to local pages with the t.navigateTo action.

fixture `My fixture` . page `http://www.example.com/` ; test ( ' Navigate to local pages ' , async t => { await t . navigateTo ( ' file:///user/my-website/index.html ' ) . navigateTo ( ' ../my-project/index.html ' ); });

⚙ Adding custom methods to the selector (#1212) #

You can now extend selectors with custom methods executed on the client. Use the addCustomMethods method to provide custom methods.

const myTable = Selector ( ' .my-table ' ). addCustomMethods ({ getCellText : ( table , rowIndex , columnIndex ) => table . rows [ rowIndex ]. cells [ columnIndex ]. innerText }); await t . expect ( myTable . getCellText ( 1 , 1 )). contains ( ' hey! ' );

Use this feature to build selectors that reflect the specifics of your web app.

⚙ Removing the native dialog handler (#243) #

We have added the capability to remove a native dialog handler by passing null to the t.setNativeDialogHandler method.

fixture `My fixture` . page `https://devexpress.github.io/testcafe/example` ; test ( ' My test ' , async t => { await t . setNativeDialogHandler (() => true ) . click ( ' #populate ' ) . setNativeDialogHandler ( null ) . click ( ' #submit-button ' ); });