This page is under construction

Unable to locate element failures

One of the most common problems you are likely to run into with test automation, one that can be difficult to diagnose and fix, is an "Element not found" error. For example:

'5/27/2011 4:31:42 PM' - 'Fail' : 4. Click 'CLink'
------------------------------------------------------------
Failure Information:
~~~~~~~~~~~~~~~
Unable to locate element. Details: Attempting to find [Html] element using
Find logic
 (Html): [tagname 'Exact' a] AND [TextContent 'Exact' ABCDE]

Unable to locate element. Search failed!

or

'6/3/2011 10:47:24 AM' - 'Fail' : 1. Verify element 'ListItem4' 'is' visible.
------------------------------------------------------------
Failure Information: 
~~~~~~~~~~~~~~~
Unable to locate element. Details: Attempting to find [Html] element using 
Find logic 
 (Html): [id 'Exact' rpbNavigator_i3_rtvROOFER][tagIndex 'Exact' li:2]

Unable to locate element. Search failed!

There are many possible causes of this problem. Before we can fix it we have to narrow down what the root cause is. To do that we have to ask the following questions:

  1. Is the test on the right page when the error occurred? Obviously if the test did not advance to the correct page, or the server experienced a fatal error trying to render the page, the element the test is looking for won't be there.
  2. Does the element actually exist on the page? Even if we're on the correct page, maybe the element isn't present for some reason. For example you have a Save button that isn't displayed until you make a change to the data being displayed.
  3. Did the structure of the page change such that the find logic the test is using is no longer valid? Most of our customers are using test automation to test a website that is under development. Changes to the website may move the element to a new location, or give it a new name/ID which causes the test to be able unable to find the element where it used to be (or the name/ID it used to have).
    1. Is the element at a new location in the HTML?
    2. Did the name/ID for the element change
    3. Does the element use a dynamic ID that's different every time you run the application?
    4. If the find logic is relying on some text content, did that text change?

 

Let's go through the list above in order in an attempt at narrowing down what caused the failure.

1. Was the test on the right page when the error occurred?

There are a couple of ways to determine this.

  1. Open the test in Test Studio and run it from the Record tab and simply watch the test run in the browser window. Make careful note of what page was displayed when the test stops on the error. To make this even easier you can select "Pause On All Errors" from the Quick Execute options before running your test. By doing this Test Studio will automatically pause the test, leaving the browser open, when it detects the failure. Then you can easily see whether or not the test is on the right page.
    enlarge screenshot
     
  2. Another option is to look at the image that was captured after the test executes and detects the failure. You get to the image by clicking on the X of the failed step, then clicking the Images tab. This will display both the expected image and the actual image of what was displayed in the browser window at the time the error occurred.
    enlarge screenshot

If we determine that the test is not on the right page we have to further diagnose why not. Some possibilities include:

  • The application is broken and the page won't load. You can determine if this is the case by manually testing your application.
  • The button was disabled when the test tried to click on it. Test scripts will run as fast as possible. Test Studio doesn't take the time to verify whether or not a button is clickable. It only verifies that it is present and visible. If there's a delay for any reason then Test Studio will try to click on it before it's ready. This end result is that the test didn't navigate to the next page. To overcome this you need to add a "Wait for enabled" test step.

    Maybe the button is disabled because the input validation didn't succeed. Some applications are designed such that the "Next/Submit/Search" button is only enabled after the user enters some data into the form. For HTML applications, setting "Simulate Real Typing" for text input, or setting "Simulate Real Click" for checkboxes and other elements may help this.

    If your application uses jQuery, maybe you need to invoke the jQuery OnChange event in order to make the data validation in your application run.
  • The test script didn't wait long enough for the page to load. As I mentioned earlier, the test script will try to run as fast as possible. Test Studio makes its best effort to synchronize with your application being ready, but that's not always possible, especially if an AJAX postback is happening. There's no hook or indication we can reliably use to detect when this is occurring or when it is finished.

    We recommend adding a "Wait For..." test step to make the test synchronize with your application. Select some UI element (some piece of text) that will only show up when your application has finished loading the page. As a last resort you can add a fixed delay to the test.

2. Does the element actually exist on the page?

Start by using the same steps to determine if the test is on the right page. Look to see if the element can be seen on the page. If the test is trying to find an element that can't be easily seen on the web page (e.g. a hidden <div> or a listbox item, etc.) look inside the DOM.

Let's take the second failure list above as an example. The find logic is saying find an element that has the id "rpbNavigator_i3_rtvROOFER" then find the third <li> element (because it's zero based) underneath it. Here's what the DOM looked like when the test failed:

<div id="rpbNavigator_i3_rtvROOFER" >
	<div id="rpbNavigator_i3_rtvROOFER_RadTreeViewContextMenuROOFER" >
		<div id="rpbNavigator_i3_rtvROOFER_RadTreeViewContextMenuROOFER_detached" >
			<iframe src="javascript:'';"></iframe>
			<ul style="cssFloat: left">  </ul>
		</div>
		<input id="rpbNavigator_i3_rtvROOFER_RadTreeViewContextMenuROOFER_ClientState" >
	</div>
	<input id="rpbNavigator_i3_rtvROOFER_ClientState" >
</div>

Notice that there are no <li> elements contained in our unnumbered list (the <ul> element). Here's a case where the dropdown combobox doesn't get populated until you actually open the combobox. Opening the combobox initiates an AJAX postback which returns the list of items to populate in the combobox. The solution was to add a test step to open the combobox before our failing step.

3. Did the structure of the page change? This can cause the find logic the test is currently trying to use to become invalid?