Fluent Bytes

"The only source of knowledge is experience" - Albert Einstein-

Testing Angular sites with CodedUI (part 2)

In my previous post I showed primarily how you can select elements based on the ng-* attributes when using CodedUI. In this post I will complete the scenario on how we can test the sample application created by my colleague MVP Maurice de Beijer, who is an Angular expert.

The Scenario

The scenario we will walk through is the following:

Goto the site http://rawstack.azurewebsites.net/, Click on the Admin link, enter a movie in the filter box, Click on one row and then read out the audience score value and assert on the value.

Below you see the steps including the screenshots so you can follow along the steps how to implement this.

Goto the site and click the Admin link

image

Enter text in the filter box:

image

Click the row with the entered text we are searching for:

image

Now check if the value in the text box is 94

image

So what are the steps we need to code in CodedUI

.We need to get started with going to the Url and then click in the admin link. this is done with the following steps:

The next step is that we want to find the filter box, as described int he previous post. The challenge we have here is that this box is not available right away. What happens is that the site goes out with an Ajax request to get a list of data and when the data is returned shows the grid with the data and the text box where we can type the filter text.

To show progress the page has an progress indicator that shows an Ajax request is ongoing and this indicator is hidden the moment the Ajax call is done.

image

We can make use of this to wait for the call to complete.  We do this using the WaitForControlNotExisits call on the TestControl. This is done as follows:

Now we can search for the filter control and we can ensure we will find it.

Finding the control is done with the steps where we will use a JavaScript execute call to find the control using the document.querySelector and find the control by it’s ng-model attribute.

This is done as follows as seen in the previous post:

So now we have filtered down the list to the number of items we are looking for and next is to find the correct row we want to click

This part is a bit tricky, since only selecting the Span that contains the text item and clicking it, will not yield the right results. If you look at the table structure for the grid you see it has multiple div’s and you need to actually select the row div that contains the click handler to trigger the click that a user would normally trigger. If you look with the F12 tools on any of the browsers you will see the following structure:

image

So to find the correct row we can simply use the power of CodedUI searches. We only need to add two SearchProperties to find the correct div and then we can click it. We need to search for both the InnerText and the CssClass on the Div and use the PropertyExpressionOperator.Contains. The code for this is as follows:

After clicking the row we now will see the admin page for this row and we can finally search for the audienceScore input. This control has an Id, so the search for that is very simple and robust. Reading out the value and then asserting on that is nothing more then reading the Text property and asserting on that value. The code for that is as follows:

And that is all to make it work.

Implicit wait on Ajax by CodedUI

One final note is that CodedUI injects a small piece of JavaScript into you application on startup in order to be able to check if all UI threads and Ajax calls have completed. In this application this resulted in the Ajax busy indicator to keep spinning.  I removed the need of CodedUI to do the wait implicitly, by the explicit wait I do for the Ajax call to complete. So I added the following line of code just before I start the browser window:

This prevents the JavaScript to be injected and this solved the spinner being stuck in the application.

Conclusion

So you see that there are primary tree caveats in testing this angular application. The first one is waiting on the Ajax call to complete without relying on the default codedUI WaitForReadyLevel. We used the WaitforControlNotExists to wait for the operation to complete. The second one is finding controls based on the ng-* attributes in stead of unique identifiers, which we solved by using the JavaScript execute method on the BrowserWindow class. The last one was selecting the right Div on the Angular grid Control so the click is actually executed.

The solution I showed here works cross browser, so by just setting the BrowserWindow.CurrentBrowser = “crome” or “firefox” you can run this test also on chrome or Firefox with the same results.

Hope this helps,

Marcel

CTO at Xpirit, Microsoft Regional Director, Visual studio ALM MVP, Speaker, Pluralsight Author and IT Architect Consultant

4 Comments

  1. Hi,
    We have a xml repository for specifying the search attributes. And we have a repository generator exe file that will automatically create a cs file on build. This file is used by our code. currently our framework is not supporting angular JS. It is not identifying the page itself with angular elements. Do you have any solution?

  2. Hi Marcel,

    Thank you for all your blog posts on CodedUI. I have also watched all your pluralsight videos on this topic. They have helped me tremendously.

    I noticed that they are not nearly as many online resources for CodedUI compared to other test automation framework (e.g. Selenium). Do you know any forums or communities that could help me understand CodedUI in depth or help me answer any related questions I might have?

    Thank you so much!

Leave a Reply

Your email address will not be published.

*

© 2017 Fluent Bytes

Theme by Anders NorenUp ↑