As long as I use PageObject pattern I wondered where should I wait for element on dynamic pages. Assuming we have test method and pageObject class. Should I do something like (in test method):
- Click on button
- Wait for element to be displayed
- Verify the element (contains eg. method isElementDisplayed())
Or maybe there is other good practice to wait for the element? Maybe we should wait for element in method isElementDisplayed which is in PageObject.class?
Another efficient concept of test page(Since selenium 1) from one of the selenium testing-frameworks - ISFW can be utilized over here. It has lazy loaded element, custom component feature and auto wait (not implicit wait that reduce performance), inbuilt wait methods with element and other features that are very useful for ajax bases application.
It provide following building blocks for developing test case:
In addition Reporting is also descriptive.
You should wait for elements in your page object class, not in test class, because your elements should be defined in page object class, test class should know nothing of any elements, selectors or similar. Tests, IMHO, should contain only chains of method calls that describe the test flow, all the interaction with the website and underlying DOM should take place in Page Object class.
So an overly verbose method to wait for some element to appear could be something like:
In plain words, the function if polling the DOM for 60 secs (every 1 second) to see, if the element exists in DOM and it is visible (means has height and witdh greater than 1px). If the element exists (and is displayed), the function returns the found element and stops the polling (although
isLoaded()
method does not return the element in this particular case).It makes sense to ignore
NoSuchElementException
which can be thrown byfindElement
method in case the element is not found, andStaleElementException
, which indicates that a reference to an element is now "stale" - the element no longer appears on the DOM of the page. This usually means, that something (most commonly JS) has modified the DOM and the reference is no longer valid, hence theWebDriver
needs to look it up again.Of course shorter code would also to the trick, something like:
The documentation is actually pretty good on this.
EDIT: answer to the comment:
Lets say you have a scenario, where you have a button and after clicking that button a textbox appears and you want to interact with it.
And now your test class: