Using JQuery Selectors in CodedUI

CodedUI has come a long way in the last couple years especially when it comes to testing web applications.  However, even with the help of great frameworks like CUITe, it can still be difficult and slow for CodedUI to find controls on the web page.  

Thanks to recent improvements, you can more quickly and easily find controls by injecting Javascript into the page under test.  Even better, injected Javascript returns controls much more quickly than regular CodedUI searches. If you are loading JQuery on the page, this extension lets you find one or all controls that match a JQuery selector:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UITesting;

namespace TestingExtensions
{
    public static class JQueryExtensions
    {
        public static IEnumerable<T> FindControlsBySelector<T>(this BrowserWindow window, string selector)
        {
            var controlsBySelector = (IEnumerable<T>)window.ExecuteScript(string.Format("return $('{0}')", selector));
            return controlsBySelector;
        }

        public static T FindControlBySelector<T>(this BrowserWindow window, string selector)
        {
            object scriptResult = window.ExecuteScript(string.Format("return $('{0}')", selector));
            
            if(scriptResult == null)
                throw new InvalidFilterCriteriaException(string.Format("Could not find a control with the selector {0}", selector));
            bool isList = scriptResult.GetType() == typeof(List<object>);
            if (scriptResult.GetType() != typeof (T) && !isList)
                throw new InvalidCastException(string.Format("Incoming script result is not of type {0} - It is defined as {1} - with String of {2}", typeof (T).Name, scriptResult.GetType().Name, scriptResult));

            if (isList)
            {
                return (T) ((List<object>) scriptResult).First();
            }
            else
            {
                var controlBySelector = (T)scriptResult;
                return controlBySelector;    
            }
            
        }

    }
}

Use it like this:

myWindow.FindControlBySelector<HtmlSpan>("div.room.selected > span:not(span.check)");