Tuesday, October 6, 2015

Thoughts on C# and reimplementing the Abstract PageObject Pattern with C#

Quick Thoughts on C#

I've started a new job in a C#.Net shop after working in Python for 1 1/2 years.  One of the things I'm dealing with now is re-writing some of the framework stuff I've written over the years in C#.  There are some things I like and don't like about C# vs Python.


  • I like strongly typed languages in that tools for linting, syntax checking, and re factoring tends to be much better.

Don't likes

  • Closures are a bit tricky to deal with.  In python it was very easy to go crazy with lambda statements, which I did very liberally especially with wait and exception handling wrappers.
  • Decorators didn't seem as straight forward.
  • REPL - scripting languages you can evaluate nearly anything in the REPL.  C# however, you can do somethings, but say importing new classes gets tricky.

Re-implementing Abstract PageObject pattern in C#

Thought I share this, since I've reimpelmented it in C#.  The orginal implementation I've done in Java you can find here, http://engineeringquality.blogspot.com/2012/06/creating-generic-advanced-page-factory.html.

For C#, most of it follows very similar to Java.

using System;
using System.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
namespace web
    internal class AbstractPageFactory
        /// <summary>
        /// An advanced version of Selenium's PageFactor.InitElements that uses reflection to infer subtypes.
        /// </summary>
        /// <typeparam name="T">PageObject or Interface</typeparam>        
        /// <param name="searchContext">Selenium webdriver or webelement</param>
        /// <returns></returns>
        public static T InitElements<T>(ISearchContext searchContext)
            var type = typeof (T);
            var subtypes = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(s => s.GetTypes())
            Exception lastException = null;
            foreach (var subtype in subtypes.Where(subtype => subtype.IsClass).Where(subtype => !subtype.IsAbstract))
                    var pageObj = Activator.CreateInstance(subtype, searchContext);
                    PageFactory.InitElements(searchContext, pageObj);
                    return (T) pageObj;
                catch (Exception e)
                    lastException = e;
            if (lastException != null)
                throw new NoSuchWindowException("Could not find a matching PageObject. Last exception:" + lastException);
            throw new NoSuchWindowException("No matching PageObjects found.");

No comments: