I Call Them ControlObjects

Am not 100% sure what other people are going such objects however am I calling them "ControlObjects".

By a ControlObject I mean a common UI control used throughout your application such as SelectBox, Tables, Lists, plus controls specific to your application, such as we use several of the JQueryUI controls like MultiSelectBoxes and Toggle switch.

If your familiar with WebDriver you will already know that there is a Selectbox ControlObject already available in the OpenQA.Selenium.Support.UI.SelectElement namespace, but I believe that is the only one.

I have a separate Project within my solution for ControlObjects, mainly because they are used across a lot of our applications. You might not have noticed already but within your PageObjects you have probably already written code to handle the same control, so ControlObjects could work for you.

Obviously there is a dependency to some degree that the controls are always used in the same way in each instance, but you can control this by working close to the developers, or if you are the developer always use it the same way, then using ControlObjects should save you a lot of time, and also speed up the creation of PageObjects and in turn Tests. They could also assist you in creating more methods in your PageObjects because you have already written the complex code in the ControlObject.

Maintainability is also a factor, for example if the company decides to use a new control for MultiSelectBoxes you only need to change your ControlObject and all your tests should still function.

Here is how I use ControlObjects in my code:

The reason for having the ControlObject as a property is that, its likely you are going to use several methods from your page object, so we can use the same ControlObject instead of creating a new one each time. The saving is probably not noticeable, but I feel its good practise.

I will tidy up some of the ControlObjects I have created and share them at a later date.

Do you use ControlObjects? What do you call them? Love to hear how other people approach this.

6 comments:

  1. We call them "Elements", but ControlObject is a good name for a design pattern, just like PageObject. Here's an example in C# for the Selenium RC API of a ControlObject for an HTML radio button and the radio button group it belongs to:
    using System;

    namespace Parature.SmokeTest.PageElements
    {
    /// <summary>
    /// "INPUT TYPE=RADIO" page element.
    /// </summary>
    public class InputRadioElement : ClickableElement
    {
    private InputRadioGroup groupedIn;

    /// <summary>
    /// Create a radio-button element.
    /// </summary>
    /// <param name="elementId">The ID= attribute of the element, if any.</param>
    /// <param name="xpathLocator">The XPath address that identifies this element within its container, if any</param>
    /// <param name="cssLocator">The CSS selector that identifies this element within its container, if any.</param>
    /// <remarks>
    /// At least one of the locator parameters must be non-empty.
    /// </remarks>
    public InputRadioElement(string elementId, string xpathLocator, string cssLocator)
    : base(elementId, xpathLocator, cssLocator)
    {
    }

    /// <summary>
    /// Add this radio button to the specified group.
    /// </summary>
    /// <param name="group">The group.</param>
    /// <param name="possiblyMissing">Is this element sometimes missing?</param>
    public void AddToGroup(InputRadioGroup group, bool possiblyMissing)
    {
    if (groupedIn != null)
    {
    throw new Exception("An InputRadioElement can only be part of a single InputRadioGroup.");
    }
    groupedIn = group;
    group.AddButton(this, possiblyMissing);
    }

    /// <summary>
    /// Click on the radio button, selecting it and deselecting any of its siblings.
    /// </summary>
    public new void Click()
    {
    base.Click();
    }

    /// <summary>
    /// Is this radio button selected?
    /// </summary>
    /// <returns>true if so, false otherwise.</returns>
    public bool IsSelected()
    {
    PrepareToUse();
    return SeleniumClient.IsChecked(BestLocator);
    }
    }
    }

    ReplyDelete
  2. Hello Ross,
    Thank you for commenting. Glad to see other people are following a similar approach regardless of the name.
    Yes name isn't that important, but felt was worth sharing and seeing what other people were doing.

    ReplyDelete
  3. I call them PageElements, initially wanted to call them Page Object Elements, but that would be too long to use as class suffix.

    The reason why I don't use term Control is because most of the times PageElements are not just an abstraction of a single control, but rather a hole set of controls, for example I would usually have a HeaderPageElement that would have properties such as navigation menu, login/logout link etc. And than this PageElement would be used to compose PageObjects.

    For simple controls WebDriver API provides enough properties and methods to interact with them, so I don't see an actual need for abstracting them, but for controls such as grid it would definitely make sense.

    ReplyDelete
  4. Hello Ivan, thank you for commenting.

    I called them ControlObjects because the UI developer called these things controls.

    I see what you mean by your page elements, however I tend to strip them out to just PageObjects. As like it says on the selenium wiki a page object doesn't have to be a whole page can just be a section. But both work.

    I am more referring to as you hit on at the end, Tables, MultiSelectBoxes, Accordians, DataPickers, Sliders and so for. These are used throughout our application so abstracting them makes sense, especially when the site is redesigned and different controls are used, wouldn't be so painful updating the scripts.

    Thank you again for reading.

    ReplyDelete
  5. Be careful when going that road, you could easily end up with a large testing framework that you have to maintain. I've been there and that's why I try to avoid it ;)

    Web elements are much simpler to interact with compared to desktop app controls. When it comes to testing desktop apps, it makes more sense to create such a framework, because there are many UI frameworks for desktop apps and they are automated differently. So abstracting controls, gives you ability to interact with them on same way no matter which UI framework is used.

    In a web context, abstracting grids makes sense, but I'm not convinced you'd benefit much with accordians, date pickers etc.

    ReplyDelete
  6. We call them PartialPageObjects, and have the convention that any asynchronous loading of css, js, etc done by these components can be tested for completion including all ajax. This is a by product of an the belief that if an object is successfully constructed it should be immediately usable.

    ReplyDelete