Monday, August 24, 2015

Do you use CodedUI for testing responsive webdesign?

Responsive web design has been around for quite some time. Most of the websites created nowadays are built with responsiveness as a main design consideration. But still automating responsive website testing is not adopted in software teams very well. Marcel has a nice post on how to resize the browser window to test responsive websites.

In this post, I’ll try to combine his solution with attributes to specify the view port details and then use this information to test responsive websites.

Use extensions methods to resize Window

public static class BrowserWindowExtensions
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

    public static void ResizeWindow(this BrowserWindow control, int width, int height)
        SetWindowPos(control.WindowHandle, (IntPtr)(-1), 0, 0, width, height, 0x0002 | 0x0040);

Use attributes to specify ViewPort

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class BrowserViewPortAttribute : Attribute
    public BrowserViewPortAttribute(int width, int height)
        Width = width;
        Height = height;

    public int Width { get; private set; }
    public int Height { get; private set; }

The BrowserViewPort attribute can be now used in the CodedUI test class or test methods to define the ViewPort.

[TestCategory("Lumia 930")]
[BrowserViewPort(320, 525)]
public void Google_ViewPortSample()
        .Create<GooglePage, GoogleMap, GoogleValidator>("", TestContext)
        .ValidateNugetResultsLastItemAs1("Hosting Your Own NuGet Feeds");

Extend the TestContext to expose ViewPort information

public static class TestContextExtensions

    public static BrowserViewPortAttribute GetViewPort(this TestContext context)
        var testClassType = Assembly.GetExecutingAssembly().GetType(context.FullyQualifiedTestClassName);
        var classViewPort = testClassType.GetCustomAttribute<BrowserViewPortAttribute>();
        var testMethodInfo = testClassType.GetMethod(context.TestName);
        if (testMethodInfo == null)
            return classViewPort;
        var methodViewPort = testMethodInfo.GetCustomAttribute<BrowserViewPortAttribute>();
        return methodViewPort ?? classViewPort;

Use these in the page factory to create PageObjects

private static TPage CreatePage(string url, TestContext context, bool disposeOnPlayback = true) where TPage : BasePage
    where TMap : BaseMap where TValidator : BaseValidator
    var window = BrowserWindow.Launch(new Uri(url));
    if (context != null && context.GetViewPort() != null)
        var viewPort = context.GetViewPort();
        window.ResizeWindow(viewPort.Width, viewPort.Height);
        window.Maximized = true;
    if (!disposeOnPlayback)
        window.CloseOnPlaybackCleanup = false;
    var map = Activator.CreateInstance(typeof (TMap), window) as TMap;
    var validator = Activator.CreateInstance();
    var page = Activator.CreateInstance();
    validator.Map = map;
    page.Map = map;
    page.Validator = validator;
    return page;

No comments: