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.

My Page Object Approach

So I have been using a page object (PO) approach for a while now, but not been blogging for long, so am going to mark the below as "My Page Object Mach 1", and will continue the theme as my PO's involve.

So to start with I have abstract class which we are going to call DefaultPage, this is essentially my default PO, but it started by just handling WebDriver, like so:

It has since evolved into having several methods for interactions I found myself repeating, such as populated and reading fields, and dealing with Select boxes.

Then each of my page objects inherits the DefaultPage.

The basic structure of my page objects is:
  • Initiate locators.
  • Wait for a specific element
  • Assert that the application has taken you to the correct page, using a specific attribute of an element or could use the URL depending on your application.
Edit: I no longer agree with Assertions in PageObjects. The PageObjects job/role is to allow a test/check to interact with a page, a test/check would soon tell you there is an issue when the PO fails to serve the request. And if you are always running all your tests/checks, which you should be otherwise why bother to create them, you know soon enough if the page header isn't correct!

Which looks like:

I parameterise the timeout value, as I required to increase it for specific tests / environments, so made sense to make it default page of my approach.

I have heard people not recommend putting asserts in your page objects, however I believe that should be the rule for the methods but serves a good purpose in the constructor.

Then objects are instantiated like so:

Perhaps for another post, but I believe this is a good approach, and as mentioned above you can add common methods to the default page.

Appreciate all comments.

Take Screenshots With RemoteWebDriver

So am currently working on a project that I intend to post about soon, and ran into an issue when trying to take screenshots using RemoteWebDriver.
Turns out that RemoteWebDriver doesn't have the capability that the other drivers have, however after a few searches I managed to find a solution and with a small tweak got it working.

So here is how you can take screenshots using RemoteWebDriver.

You need to create a class that extends RemoteWebDriver and inherits ITakeScreenshot, should look like this:

The issue I had was that the example I found by Jim Evans, must have been when RemoteWebDriver didn't have any paramters, so had to include the URI and Capabilities.

To use this now you have to use your ScreenShotRemoteWebDriver instead of RemoteWebDriver, like so:

Then you can take a screenshot using the following code:

Note that the screenshots are saved on the machine where the test is being executed from, not the client.

Happy screenshoting!

* Update *

There has been lots of changes in RemoteWebDriver since I wrote this original post, one of those is that screenshots are now a lot easier as per Jan Zdrahal comment below.

So you can now create an extension for IWebDriver to take a screenshot for you that will also work with RemoteWebDriver.

Then you can call the method like so.