Limited Time Discount from Packt Publishing and The Morning Dew – 50% off eBooks

Hello Dear Readers.

For the next week, Packt Publishing is offering readers of The Morning Dew 50% off eBooks with code VKAMATHP50. The discount code is valid until September 24, 2015. Check out the banner on the right for a few of the featured titles.

Packt-Banner

Happy coding!

Alvin

 

The Dew Review – DevExpress TestCafe

Hot on the heels of my last review for DevExpress Universal 2014.2, I will next dive into my recent experiences with DevExpress TestCafe.

Introduction

TestCafe is the functional web testing tool from DevExpress. While many web test products work in conjunction with browser plugins, TestCafe works without plugins on any browser that supports HTML5. In today’s world, that translates to ‘any modern browser’.

You can also run on the big three operating systems, Windows, Mac OSX and Linux. I have been working with TestCafe on Windows 8.1, Windows 10 and OSX Yosemite. This operating system and browser agnostic ability affords maximum flexibility for web developers to test applications across multiple versions of browsers. All that is required is another physical or virtual machine running the desired browser(s).

That all sounds great, but you probably hear a lot about cross-browser, cross-platform ability these days. Take a minute and think about what that really means for a functional web testing tool. I can open TestCafe from any browser that can access the machine(s) where TestCafe and my application under test have been installed. So, I can pull out my Ultrabook on the road and record new tests over my company’s VPN. I could also break out my iPod Touch, tablet or Windows Phone and execute test fixtures. That is pretty powerful.

Getting Started

TestCafe claims to be “Functional Web Test, Made Easy”. Let’s see how easy it is to get started using the product. Until last month, I have never used TestCafe. In fact, I never used any kind of web test automation product. I’ve been lucky enough to work for organizations that understand the value to QA and hire dedicated testers who find my bugs that get past my own unit testing and manual testing.

So, how does a newbie like me get started?

DevExpress Demo Pages

A great first place to start is by trying TestCafe through the online demo pages. There are three pages available for selection.

  • TestCafe Example Page
  • ASPxGridView Demo Page
  • ASPxFileManager Demo Page

I decide to try the ASPxGridView Demo Page, so I select it from the list and click the ‘Run Demo’ button. Here is what I see initially.

TestCafe 3 - Demo Step 1 

Figure 1 – Run the online demo

I click the Start Demo link and click through some controls on the grid to auto generate a few test steps.

TestCafe 4 - Demo Step 2

Figure 2 – Online demo test steps

TestCafe includes all of my clicks and keystrokes into the test steps (even my screen capture keystrokes in Step 5 J). Now I can add some assertions to my test fixture or playback the steps that have been generated so far.

After completing this quick demo, I feel ready to jump into the Online Tutorial and create some of my own tests on my development machine.

Online Tutorial

From the main page for TestCafe, there’s a big button that will take you to an online tutorial with videos and step-by-step instructions for getting started with your first tests.

TestCafe 01 - The big button

Figure 3 – The big button.

The online tutorial steps you through creating a project, recording tests, running them, and finally running on remote devices. Here’s a look at the complete outline of the tutorial’s steps.

Test Cafe 02 - Tutorial Steps

Figure 4 – Tutorial Steps

Completing the online tutorial will give you an idea of the base functionality and capabilities of TestCafe. Now it’s time to take that knowledge to the next step.

AngularJS PhoneCat Tutorial App

Now that I have taken some time to familiarize myself with TestCafe using web pages created by DevExpress, I want to try creating a few simple test fixtures with a page that uses one of today’s most popular JavaScript frameworks, AngularJS. I have been working mainly in the world of Windows desktop applications and WPF for the last 18 months, so I turn to Bing to find out how to set up and run a simple AngularJS site.

Not surprisingly, Bing takes me to the AngularJS site where I see that there is a Tutorial under the Develop menu. The tutorial walks you through downloading their sample site, setting it up with Node.js and npm, and running it. The sample site is a simple catalog of Android devices with a list view and detail view.

TestCafe 05 - PhoneCat 1

Figure 5 – AnguluarJS tutorial application – list view

TestCafe 06 - PhoneCat 2

Figure 6 – AngularJS tutorial application – detail view

I create a new Test Project and Test Fixture and record a few tests for the List View page.

TestCafe 07 - Phone List Tests

Figure 7 – Phone List tests

Up to this point everything has been produced for us by TestCafe. Let’s take a moment analyze what has been generated for the tests I created for the Phone List Page. Here’s the JavaScript that is presented when clicking the Edit button on one of the tests or on the Test Fixture itself.

"@fixture Phone List Page";
"@page http://localhost:8000/app/index.html";

"@test"["Sort Phone List"] = {
    "1.Click select": function() {
        var actionTarget = function() {
            return $(".ng-pristine.ng-untouched.ng-valid").eq(1);
        };
        act.click(actionTarget);
    },
    '2.Click option "Alphabetical"': function() {
        act.click(":containsExcludeChildren(Alphabetical)");
    },
    "3.Click select": function() {
        act.click(".ng-untouched.ng-valid.ng-dirty.ng-valid-parse");
    },
    '4.Click option "Newest"': function() {
        act.click(":containsExcludeChildren(Newest)");
    }
};

"@test"["Search Dell"] = {
    "1.Click input": function() {
        var actionTarget = function() {
            return $(".ng-pristine.ng-untouched.ng-valid").eq(0);
        };
        act.click(actionTarget);
    },
    "2.Type in input": function() {
        var actionTarget = function() {
            return $(".ng-pristine.ng-untouched.ng-valid").eq(0);
        };
        act.type(actionTarget, "Dell");
    }
};

"@test"["Search Samsung"] = {
    "1.Click input": function() {
        var actionTarget = function() {
            return $(".ng-pristine.ng-untouched.ng-valid").eq(0);
        };
        act.click(actionTarget);
    },
    "2.Type in input": function() {
        var actionTarget = function() {
            return $(".ng-pristine.ng-untouched.ng-valid").eq(0);
        };
        act.type(actionTarget, "Samsung");
    }
};

"@test"["Search Motorola sort by name and assert first device name"] = {
    "1.Type in input": function() {
        var actionTarget = function() {
            return $(".ng-pristine.ng-untouched.ng-valid").eq(0);
        };
        act.type(actionTarget, "Motorola");
    },
    "2.Click select": function() {
        act.click(".ng-pristine.ng-untouched.ng-valid");
    },
    '3.Click option "Alphabetical"': function() {
        act.click(":containsExcludeChildren(Alphabetical)");
    },
    "4.Assert": function() {
        eq($(":containsExcludeChildren(DROID 2 Global by Motorola)").text(), "DROID™ 2 Global by Motorola", "First Moto Device");
    }
};

Notice that the test fixture is designated with @fixture, and each test definition with @test… pretty straightforward. Each test step is a function that returns the UI element to act upon followed by the action to perform on that element. My final test includes an assert as a final step. This checks that the first list element’s text is equal to what is expected after searching for Motorola and sorting the results alphabetically.

I can access the test fixture on my Windows Phone’s browser.

wp_ss_20150307_0002

Figure 8 – TestCafe on Windows Phone 8.1

And I can kick off a test run.

wp_ss_20150307_0001

Figure 9 – Tests executing on Windows Phone 8.1

So, that is a quick look at some of the basics of getting TestCafe up and running. There is a lot you can accomplish without knowing much more than what the Online Tutorial provides. To learn some more advanced features of the test fixtures in TestCafe, refer to the Test Fixture API Reference guide in the online documentation.

Feature Focus – Continuous Integration

I am a big fan of automated builds and continuous integration (CI) in development. I think it is one of the essentials of creating quality software. CI can do things for your team like running unit tests, code analysis and enabling continuous deployments to dev and test environments. Even at a bare minimum, CI can provide immediate feedback if a change one developer makes in a software component breaks something else in the system.

Automating and integrating functional web tests with CI builds is an extremely valuable proposition. It means that the number of regression bugs discovered by QA will be greatly reduced as builds that fail test steps in TestCafe will never be deployed to QA environments.

TestCafe has an entire section of their online documentation dedicated to continuous integration as well as a CI API reference.

At a glance, these are the steps that will need to be completed to set up CI for most types of servers (taken from the online docs).

  • Copy your tests to the server.
  • Setup TestCafe on the server.
  • Write a Node.js application that runs the tests and logs the results.
  • Call the application from your Continuous Integration system.

The sample node.js app in the online docs logs results to the console. Depending on your CI system, you will either use this method and pick up the results through the console output, or you may want to log the output to a file. There is an example of file output on another online documentation example. Here’s a snippet of that example:

var fs = require('fs');
 
testCafe.runTests(runOptions, function () {
      testCafe.on('taskComplete', function (report) {
           log('\n' + new Date().toString() + ':\n' + JSON.stringify(report));
       });
});
 
function log(mssg) {
       fs.appendFile(LOG_FILE_NAME, mssg, function (err) {
             if (err) 
                throw err;
       });
}

My current build server of choice at home and at work is JetBrains TeamCity. I have also used CruiseControl .NET in the past. While the basic steps were a good starting point, I wanted to find more detailed instructions specific to my TeamCity implementation.

Getting Support

I want to find out more information about TestCafe continuous integration with TeamCity. Where do I turn? To me, the logical first step is to try the Support page on the TestCafe site.

I kept it simple and searched for “TeamCity” and got just a single search result. Luckily, this one result was exactly what I needed. There is no direct support between TestCafe and TeamCity, but they can be integrated using the node.js app approach detailed in the online CI documentation. The method for doing this is similar for Jenkins CI servers, and Marion the DevExpress support representative who answered the question provided a link to the Jenkins information.

The TeamCity equivalent of these Jenkins steps include:

· Create a node.js app and place it on the build server. (The app in the Jenkins example will serve.)

· Install node.js on the build server.

· Add a Windows Command Line step to the desired build configuration in TeamCity that executes the node.js app.

· Capture the result.xml as the build report output.

If you want immediate feedback on your continuous builds, you will probably want to limit the number of tests run. I recommend creating either an hourly or daily build that executes all of your unit tests, integration tests and TestCafe functional tests.

Wrapping Up

Automating your functional tests can provide a great deal of value to any product. It takes a huge load off of the QA department once a full test suite has been created for your web applications. The licensing cost of TestCafe makes it something that every development shop should consider, regardless of the company or team size.

Go give it a try. There’s a 30-day free trial plus a 60-day money back guarantee if you’re not satisfied with the product.

 

Happy coding!

 

 

Disclosure of Material Connection: I received one or more of the products or services mentioned above for free in the hope that I would mention it on my blog. Regardless, I only recommend products or services I use personally and believe my readers will enjoy. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: “Guides Concerning the Use of Endorsements and Testimonials in Advertising.

Building an Offline HTML5 Application

clip_image002

HTML5 for .NET Developers

By Jim Jackson II and Ian Gilman

The idea that you can browse to an application while online and then go back to it when you are offline to continue reading, working, or playing goes against everything most people have learned about how the internet works. This offline capable concept is, however, gaining momentum and familiarity with users. This article based on chapter 9 of HTML5 for .NET Developers talks about building offline applications.

Suppose your partner is upset because you never seem to remember to buy lettuce, carrots, and celery while you are at the grocery store. Perhaps your forgetfulness has to do with the fact that you do not like to eat vegetables; in any case, you know that the criticism is deserved and you have committed to never forget the lettuce again. To that end, we will design and build a simple shopping list application that can be edited either online or offline. This way, your partner can add vegetables to the list, and you can access it even when you are at the grocery store. Figure 1 shows the simple, usable interface that we will be creating.

clip_image004

Figure 1 The complete application will allow a user to add and remove shopping items regardless of whether or not they are currently connected.

The basic premise of an offline web application is that, with specific directives in the markup and careful site preparation, you can actually take your application with you even when you are not connected to a network. With this feature though come some unique challenges and important design decisions. To make your current site or HTML application available offline you must first inventory the resources that you currently use. Every file you include in your site will need to be evaluated against the following criteria:

  • Is the resource static or is it dynamically called?
  • If the resource is static, should it be available when the application is offline?
  • If not available when offline, should a substitute resource be provided?
  • If the resource is dynamic; how will the application handle requests for it when no network connection is available?

Going offline vs. being offline

There are two scenarios that you will have to consider when building your offline web site. The first occurs when a user is online and then loses connectivity. This could be because they were using a portable Wi-Fi device and walked out of range or because the airplane mode was switched on. Whatever the reason, the important part is that the page was not reloaded and the browser was not closed and reopened but the network connection was suddenly unavailable. In this scenario, you need to track the current connection status from within the page.

The second scenario is when the user visits an offline-accessible page and then closes the browser. When the user reopens the browser and navigates back to the page, there is no connection so nothing can be loaded from the server. At that stage, all content previously saved to the cache is loaded.

Both of these scenarios imply the ability for the page to suddenly come back online. When that happens, the page should be notified and any connection-related functions should fire. That brings us to the problem of data synchronization.

For your shopping list app, our first thoughts relate to design considerations. The application must show the user when they are connected or disconnected. A simple cue on the screen will help us there. Then, we must decide how to store the data generated locally so that it can be synchronized back and forth with the server. Our application will use LocalStorage and an MVC controller to handle the storage and synchronization. Finally, the client-side logic must work the same from the user’s perspective whether connected or disconnected and gracefully handle changing connectivity states internally. This is where the Offline HTML5 API and some smooth jQuery operations come in.

Using ASP.NET MVC with offline HTML5 applications

While this application will be built on an MVC (Model View Controller) platform using a simple JSON controller for the data synchronization and a singleton object to emulate a data storage server, the page we will be visiting will not be an MVC view. Instead we will use a simple HTML page. We must do it this way because offline web applications require a physical page to reference as the starting point for the offline cache. The standard MVC application, by comparison, only presents a URL end point, not a physical file.

With design considerations considered, in this article, we’ll create the basic site structure and then the offline JavaScript library.

Creating the basic site structure

Start by opening Visual Studio and creating a new ASP.NET MVC Web Application and call it ShoppingList. Be sure to make it an Internet Application that uses the Razor engine and HTML5 Semantic Markup when you come to the New Project Dialog. Using MVC allows us to create a controller to feed data to and from the client via Ajax, but remember that it does not allow us to use a Razor view for our offline application.

Inside the new solution, we first need to create our offline page. To do so:

  • Right-click on the solution node and select Add > New Item > HTML Page.
  • Name the new page Shopping.htm, after which your page should now appear in the application’s root folder.
  • Inside the new page, add the complete markup.

Much of the code within that file is unremarkable and not worth discussing here. One thing we do want you to note about the initial markup is the attribute in the opening <html> tag that points to a file named app.manifest.

<!DOCTYPE html>
<html manifest="app.manifest">

<head>
...
</head>

<body>
...
</body>

</html>

App.manifest is the file that, by its presence, tells the browser that this page should be available offline. More on the contents of that file shortly.

Next is the styling for the application. In Solution Explorer:

  • Right-click on the Content folder and select Add > New Item > Style Sheet.
  • Name the new stylesheet offline.css.
  • Grab the required markup and add it to the stylesheet (see HTML5 for .NET Developers for the code).

We will be creating a brand new set of styles for our offline application since it is not necessary to duplicate the normal tabbed interface in the rest of the application. This will give the user a cue that this page is different and allow us to keep things as streamlined as possible.

Telling the user that a site is available offline

The CSS file is a good opportunity to think about how to let your users know that the site they are visiting is available offline. Each application is different so it is more important to understand the scope and nature of the problem rather than specific suggestions for resolving it.

The first part of the problem is letting your users know in a fluent fashion that the site they are visiting will be available to them later even if they are not connected. It is unnatural for a user to consider opening a browser on a device when he or she knows that there is no connection. So what kinds of indicators on the site could provide that cue? Additionally, you will probably only be building a subset of the site’s functionality for offline consumption. How can this be indicated to the user?

Next, while a user is working with the site, it is reasonable to expect an occasional loss of connectivity. What are some ways that your application can tell the user what has happened and that there is no cause for concern because their work is being saved locally?

The area of offline web pages is still very new so little or no research has been done to standardize on a method of identifying these conditions to your users. This leaves the door open to practically any solution with your creativity being the only limitation. Chrome, for instance, will change its home page to monochrome icons if the system is not currently online. This is a very intuitive indicator but you might choose to include an icon or glyph in the corner of the browser window that shows the currently connected status. Even a banner that appears temporarily in your site is not unheard of, though some might consider it heavy handed. Your final solution should make it very clear to anyone visiting the site what is possible and what the current connectivity status is. Any less that this is a recipe for confusion or worse: an unused web site.

The offline JavaScript library

The next step is to build our JavaScript interface. This will help sort through which functions are responsible for which tasks during execution. Our offline HTML application will use local storage to contain two kinds of data. The first is the current list of shopping list items and the second is a listing of required actions to update the server to reflect the client state. We will also add some utility functions to keep things manageable and reduce duplication of code.

We have not created the main.js file in the Scripts folder of our site yet, so, do that now. Open it and add the code in listing 1 to stub out our entire API. This code creates the outline that you can fill in as you dig deeper into offline applications. (Remember, if you have any questions about where specific pieces of code fit in the main.js file, the complete listing is in the book.)

Listing 1 The JavaScript API for the offline web application
/// <reference path="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.7.1.js" />
/// <reference path="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.7.1-vsdoc.js" />

$(document).ready(function () {
    Main.init();
});

window.Main = {
    $status: null, #A
    $input: null, #A
    shoppingItems: [], #B
    itemActions: [], #C
    init: function () { #D
},

updateForNetStatus: function (connected) { #E
},

newItem: function (title) { #F
},

loadState: function () { #G
},

saveState: function () { #H
},

syncWithServer: function () { #I
}
};

#A The ShoppingList object will contain a place holder for the status and input elements to prevent us from having to requery the DOM every time

#B Keeps a list of current shopping items

#C Keeps a list of all items that must be synchronized to the server

#D Initializes the object

#E Starts listening for the current online status

#F The newItem function updates the user interface with a new element and then assigns that element’s delete key to an anonymous function

#G The loadState function is called when initializing the screen and pulls data from LocalStorage, calling newItem on each value

#H saveState takes all items in the local shoppingItems array and update LocalStorages with the same.

#I Finally, syncWithServer takes the all items cached for server updates and sends them off

This JavaScript file is the last client side file you need before starting the process of making the site available offline.

Summary

Offline web applications can be robust and responsive in most modern browsers and the proliferation of tablet-based devices with only Wi-Fi support should increase their popularity. The biggest drawback is still the fact that users are unaccustomed to using a web site while not connected. Once this barrier is overcome though, proper design and attention to details in an offline application will yield a rich experience and a web site that is usable in many more circumstances than has been traditionally possible in web development.

In this article, you learned about creating basic HTML and CSS structure and developing a JavaScript interface as part of the process of building an offline HTML5 application.



Here are some other Manning titles you might be interested in:

clip_image006

Quick & Easy HTML5 and CSS3

Rob Crowther

clip_image008

Sass and Compass in Action

Wynn Netherland, Nathan Weizenbaum, and Chris Eppstein

clip_image010

Secrets of the JavaScript Ninja

John Resig and Bear Bibeault