eXpressApp Framework Team Blog

This Blog

XAF - Using TestCafe for Functional Testing of Our Mobile UI

In addition to the Mobile UI features announced last month, we've been hard at work improving the quality and stability of mobile apps generated via XAF's mobile UI platform. Specifically, we have developed an internal functional testing system based upon TestCafe and successfully used it with our internal tests apps (MainDemo.Mobile among others). This online demo also uses our new DevExpress Logify service to track exceptions and improve overall product quality.

Frankly speaking, the main reasons we chose TestCafe was its simplicity and flexibility. TestCafe can be installed as npm package with a simple command, and its API can emulate all necessary webpage actions. We're using our own wrappers for the Selector function to find different element types:

const activeViewSelector = Selector('.dx-active-view');
const textboxClassName = '.dx-texteditor-input';
this.findTextBox = function (fieldName) {
    return activeViewSelector.find('div[data-options*="name: \'' + fieldName + '\'"]').find(textboxClassName);

We've also implemented custom wrappers for TestCafe actions (click, drag, etc.) to handle the moment wherein all the activities on the page (animation, movements, queries) are complete and all required elements become visible: = async function () {
     await this.waitElementToAppeared.apply(this, arguments);
     await, arguments);
     await this.wait(); 
     await checkForExceptions();
These wrappers are combined in a large helper (I will not show its full source code here) that allows us to write cleaner and more user-friendly test code. For instance, this is what a test case looks like:

import { Selector, ClientFunction } from 'testcafe';
import { XafMobileTestHelper } from './lib/helper';
var helper = new XafMobileTestHelper();

.beforeEach(async (t) => {
    helper.testCafe = t; await t.navigateTo('http://localhost/');
    await helper.switchToIframe("#simulatorFrame");
    await helper.typeText(helper.findTextBox("UserName"), "Sam", { replace: true });
    await"Log On"));
test('Delete action(action with detail view)', async t => {
    await helper.typeText(helper.findTextBox("Subject"), "Task To Delete");
    await t.expect(helper.findListViewRecord("Task To Delete").exists).ok();
    await"Task To Delete"));
    await t .expect(helper.findListViewRecord("Task To Delete").exists).notOk();

Running tests and accumulating results is easy with TestCafe via a single command line:

Our mobile tests are integrated into the advanced and CCTray-based system used for automated execution and monitoring of all our unit and functional tests:

If you are interested in learning more about our Mobile UI (CTP), check out eXpressApp Framework > Getting Started > XAF Mobile (CTP) Tutorial and feel free to contact us with any questions or suggestions via the Support Center (

Published Jun 05 2017, 09:36 PM by
Bookmark and Share


No Comments

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at or call us at +1 (818) 844-3383


DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, Delphi, HTML5 or iOS & Android development. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2018 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners