Fluent Bytes

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

Selenium syntax for CodedUI

I have been playing around with this idea for quite some time and I already build this for a customer in the past, but after questions I got from people using CodedUI who tried to come up with a simplified syntax I thought it would be time to publish what I have at the moment.

If you hand code your test automation with CodedUI, then you know that searching for a control is always a couple of lines of code to set up a search. You first create an instance of the control you need, provide it the search scope in the constructor and next you need to set the search properties. Once that is done you can then use the control and the moment you use one of it’s properties it will search for your control.

With Selenium this is a bit different. You have the Driver class that provides more or less to primary methods. FindElement and FindElements and you provide it an instance of the By class that contains the search criteria.

Let me illustrate what I mean with two examples. Bot do the same. We goto the google home page and type a search query.

CodedUI:

Selenium:

In general I hear that people like the Selenium syntax more then the multistep aproach in codedUI. The thing I dislike is that I lose the type safety of the type of control. So the question is, would it be possible to get the same syntax for codedUI and still use codedUI and get a type safe way of interacting with the search controls?

The awnser is (of course) yes this is possible by creating a couple of extension methods and a nifty implementation of the By class.

So let me first show you how this looks when you use the extension methods I created:

CodedUI with Selenium Syntax:

So now I have the type safety I am used to with codedUi but I have the more terse syntaxt for finding elements of a certain type.

So how does this extension method look like?
So first I created an extension method on UITestControl that looks like follows:

 

now the magic is in the fact that we pass this function a function that can initialize the control we just instantiated with the right search properties.

This is the implementation of the By class I just mentioned. It looks like follows:

 

Now the only thing we need to do is implement this on all the standard types of ways to find a control. So that would be by CSS class, By CSS query, By innerText, etc.

the final thing we need is an extension method on the UITestControl for handling mouse clicks and keyboard handling. those look like follows:

The final thing I did was also implement the way we do a search by css query a bit different. As I described in previous posts the way to find a control based on e.g. custom attributes as is the case with Angular sites, I use an implementation that calls a piece of Java script. This will then return the object and we need to ensure it is of the type we expect. Only restriction is that this is called on a UITestControl of the type BrowserWindow. Unfortunately I have not found a way to enforce this in the compiler, so I implemented that as a runtime check.

The code for this looks like follows:

I put the final code here on GitHub, so you can easily download and contribute if you have additional insights.

What I shared is not complete, but I rather share it now then wait for me to find the time to finish it to support the whole Selenium set of methods.

Let me know what you think.

Hope this helps!

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

3 Comments

  1. John Pritchard

    May 24, 2017 at 1:36 pm

    Hi Marcel. I’ve been looking through your implementation for a project I’ve been working on and I like the syntax as it concisely allows searching for elements.
    A couple of things I’ve noticed:
    It’s possible to add a compile-time check for BrowserWindow if you only have one controlConstructorFunct per object by having two copies of the FindElement function:

    public static T FindElement(this UITestControl container, Func controlConstructorFunct)

    and

    public static T FindElement(this UITestControl container, Func controlConstructorFunct)

    and then changing the CssSelector function to:

    public static Func
    CssSelector(string cssSelectorToFind)

    However I’ve modified the FindElement function to:
    public static T FindElement(this UITestControl container, Action[] controlConstructorFuncts)

    for the application that I’m coding as it allows me to add multiple search parameters and I’ve also added the static classes Contains and FilterBy for contains search properties and filter properties respectively.

  2. John Pritchard

    May 24, 2017 at 1:46 pm

    It seems the generics got stripped from my post, the functions were as follows:
    public static T FindElement(T)(this UITestControl container, Func(UITestControl, HtmlControl, HtmlControl) controlConstructorFunct)

    public static T FindElement(T)(this UITestControl container, Func(UITestControl, T, T) controlConstructorFunct)

    public static Func(HtmlControl,BrowserWindow,BrowserWindow)
    CssSelector(string cssSelectorToFind)

    public static T FindElement(T)(this UITestControl container, Action(HtmlControl)[] controlConstructorFuncts)

Leave a Reply

Your email address will not be published.

*

© 2017 Fluent Bytes

Theme by Anders NorenUp ↑