Location, Location, Location

In my Coded UI Test (CUIT) page objects, I encapsulate locator data into a Locator object. A locator defines and specifies the search for a specific HTML control in the target web application.

The Locator object has:

  • A locator name.
  • One or more name/value pairs, each of which indicates an attribute name and value to search for.
  • A search criterion: Contains or EqualTo.
  • A status:
    • Required: The control is expected to be on the page now; it is an error if it is not present.
    • Forbidden: The control is expected to not be on the page now; it is an error if it is present.
    • Allowed: The control is allowed (but not required) to be on the page now; it is not an error whether or not it is present.

Locator Creation

A page object creates locators when it is instantiated. Many of the locators will be Required. Some may be Forbidden or Allowed.

Locator Maintenance

The page object is responsible for maintaining the status of its locators. For example, if a locator is initially Forbidden, but some Javascript creates the corresponding control, the page object must change the status to Required.

More specifically, I have a user page with a delete button. If the test presses that button, the application will put up a display with buttons for confirming or cancelling the deletion. The locators for these two buttons, which have been Forbidden must now be changed to Required.

Conversely, when one of those two buttons is clicked, their containing display is removed, and the two locators must be returned to Forbidden.

The reason for this strict locator maintenance is that the page object may be called upon at any time to verify its locators’ controls: to confirm that each Required locator’s is present, and that each Forbidden locator’s control is absent.

In the Page Object: Locators, not Controls

A page object operates on an HTML element by passing a locator to a lower-level library method. That method finds the control and performs the operation. For example, a page object can call a button-click method, passing a locator; the button-click method uses the locator to find the button, then clicks it.

The page object does not retrieve a control, nor, I think, should it. It’s not clear to me when or why the object might to go “stale” (no longer reflect the state of the UI), so I prefer to get a fresh object for each operation. And, I think, doing so is just good data-hiding.

A Thorn in My Side

A very few of the HTML elements I’m interested in do not have sufficiently unique attributes to support unambiguous location. For example, there may be several h2 elements on the page, each with no attributes at all.

Perhaps the most fragile way to get at one of these is to search for all h2 elements, then take the one with the appropriate index. A change in the number or positions of the elements can break the test.

A way that’s only a little better, and one that I’ve felt obliged to use occasionally, is to find a nearby element (one that can easily be located), then “walk” the DOM (accessing parent and child elements) to get to the desired element.

I hate having this DOM-walking code in my page object, even though it’s factored into a method. Doing things this way means that there are two completely different ways the page can operate on a control:

  • The right way: Call for the operation to be done, passing a locator object.
  • The wrong way: User a locator to retrieve a control, walk the DOM to get to the desired control, then call for the operation to be done, passing a control.

Note that this means that for the same operation on different HTML elements, I need two method overloads: one that accepts a locator object, and another that accepts a control object.

A Partial Solution

A partial solution I’m considering is enhancing class Locator so that it stores one of the following:

  • Name/value pairs, representing the usual attributes in the element to be searched for.
  • The method that’s called finds the control and performs the operation.

  • A reference to a method that returns a control. The method that’s called calls the function, gets the control, and performs the operation.

Doing this would at least mean that a page object always works with a locator, and never with method that returns a control object. And that in turn would mean that if (when?) the HTML is improved, the locator could be adjusted without requiring other changes.

Thoughts, anyone?

Advertisements

One thought on “Location, Location, Location

  1. If a) you are dealing with a web app, b) your tool allows you to specify which properties you search on, and c) your management/developers will agree to it, then I recommend establishing a contract between developers and testers the only properties used for the search will be page name and html ID and that the developer will insure these are unique and (unless agreed to ahead of time) unchanging. This approach has worked for me. It avoids fragile/hard to understand tests and gives the developer a role in getting quick test results. It also allows tests to be coded without the page existing (if html id are agreed to ahead of time, and again assuming your test tool otherwise supports coding rather that recording UI tests.)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s