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 answer to 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).
- Is the element at a new location in the HTML?
- Did the name/ID for the element change?
- Does the element use a dynamic ID that's different every time you run the application?
- If the find logic is relying on some text content, did that text change?
- Is the element in a frame which has a dynamic ID, Name, URL or it uses a Dynamic query?
Let's go through the list above in order to narrow down what caused the failure.
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 "Auto-Pause On All Errors" from the Quick Execution 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.
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.
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" test step property for text input, or "Simulate Real Click" for checkboxes and other elements may help resolving 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 it was 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 post back 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 to create the wait step. To delay the test execution certain time frame - an "Execution Delay" step could be introduced to the test as well.
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:
Notice that there are no <li> elements contained in the unordered 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.
Did the structure of the page change? This can cause the find logic the test is currently trying to use to become invalid?
1. Is the element at a new location in the HTML?
If you use XPath or TagIndex to locate the element and the structure of the page has changed after the recording, the test might fail or Test Studio will click on a wrong element that has taken the place of the right element. In this case you should open the DOM again and check whether the structure hasn't changed. Using only XPath or TagIndex for locating an element is not very reliable and we don't recommend it.
2. Did the name/ID for the element change?
Make sure the name/IDF didn't change after recording the test. You can compare the find expression for the particular element and the DOM tree of the application:
<html> <head> </head> <body> <div id="myDiv"> Test </div> </body> </html>
DOM tree of our application which shows us the ID of the DIV.
Find expression of the DIV.
3. Does the element use a dynamic ID that's different every time you run the application?
If the ID is completely different every time then you shouldn't use it. The ID could be only partially dynamic. In this case you should change the find rule to contains and type only the static part of the ID:
4. If the find logic is relying on some text content, did that text change?
Here you can use the same approach like in case of changing name/ID or dynamic IDs.
5. Is the element in a frame which has a dynamic ID, Name, URL or it uses a Dynamic query?
This is remedied by using the tilde (~) character to indicate a partial match. This can be used in the BaseURL, Id, and Name fields. If the Src string contains a dynamic query, set UseQuery to False.
Visit our Frame article for detailed information.