Iām curious, how do you guys approach Waits before element interactions?
Do you prefer setting up an implicit wait with a global timeout?
Do you prefer the granularity that explicit waits provide, even if it means writing a extra line of code before interacting with an element?
Do you prefer implementing your own methods that interact with elements, encapsulating explicit waits, as well as your own logic, in it?
I know that for some of you this question doesnāt make much sense, as there are test frameworks out there such as Playwright that implement their own auto-wait strategies, which works in most cases but Iāve definitely found issues with it, and thatās why I prefer to work with a raw test framework and have absolute control over the test script.
I try to avoid them in general.
Playwright has functions that tell the code to wait until the element is in a certain state.
Otherwise, if the automation is too quick for the website, I just add an additional expect case.
I had this scenario where playwright would think it clicked a plus button next to an input field but actually the button would not be in active state (you have to click it to activate it)
But since the input field was not disabled, I clicked the button again before clicking save on the form.
Generally, explicit waits indicate optimization issues with the automation or the infrastructure. one technique I have seen is to gather the whole of the the POM before executing the tests. If the POM is loading slowly then it might even indicate a performance defect. Feel free to ignore me if Im talking out of class
Unfortunately, frameworks such as Playwright like to pretend that they are flawless, when clearly they are not.
If you do a simple Google Search for āplaywright explicit waitā, all youāll find is the link to the āAuto-waitingā section from their documentation, and that really grinds my gearsā¦
It was only when I did a little digging into their GitHub Issues section, that Iāve learned that the correct way to wait for a elementās condition is by doing e.g.
Well at least from experience, the WebApps Iāve tested do require some sort of explicit wait in (almost) every interaction with elements.
Given that theyāre usually built upon dynamic frameworks like React which arenāt as performant, and on top of that they rely on API calls that can arenāt instantaneous, testing from point A to point B is never just a matter of click click click.
So yeah, I usually can only complain about the app being slow if itās unbearably slow, to the point it greatly affects the user experience.
Well in my experience even that wait method didnāt help in one case.
The scenario was of a side menu opening but apparently playwright interacting with it (filling in the input fields in it) even before it had fully opened. Which meant that when it had to draw a line on a canvas it, failed to do it. Which in my opinion doesnt make sense, how can the code confirm it interacted with a UI element when it isnāt even visible.
Back in the days with Selenium 1 one of my instant ideas was to implement a polling with a timeout.
Something like this:
waitForElementWithTimeOut(element){
var timeout = 10
var i = 0
while(true){
if(element.isVisible()){
break
} else if (i > timeout){
throw new Exception ("Could not find $element in $timeout seconds!")
}
sleepMillis(1000)
i++
}
}
I had global/general timeouts which I could overwrite.
The same for the sleep. Some elements should be polled different.
@sebastian_solidwork Iād call that a fused wait: thereās a fuse that metaphorically burns down until the timeout is called while checking for the element to be available.
Iāve built those myself, using the same principles you have - I think itās a pretty common idea.
Though, I donāt know if I like/will keep using this approach.
I initially did this to make the development of tests scripts easier, for whoever uses the project.
But, the disadvantages are that:
you have to create those methods & encapsulate every available element interaction, (click, sendKeys, getText, etc., etc.), and store that big pile of code somewhere (I typically leave it inside the BasePage class);
just as you, I also have set my own default timeouts constants. However sometimes they are not lengthy enough, and sometimes I donāt even want to explicitly wait i.e. I more than once faced an issue where the element was clickable, yet the explicit wait was throwing an exception.
And so because of these, I had to create yet another set of overloaded methods that took a timeout parameter.
they just slow down your code because sometimes thereās just no need to wait for the element conditions e.g. when dealing with/entering keys on a static numpad.
they create an extra layer(s) of complexity between the raw use of the Driver methods, which can create hidden issues. Because not only you have to have faith in the underlying testing framework, you also have to make sure what youāve coded works as expected.
So yeah, Iām still pondering if I should continue with this path. Because Iām just adding unnecessary complexity for the sake of simplicity for the end test programmer.
I donāt do it for every element, but for every relevant.
If a certain section is reloaded I wait for the first element to be loaded as indicator that all other elements are loaded too. On the other elements I act directly, without waits.
Itās a try&error process of finding out where are the boundaries, identifying the groups of elements which are loaded/tendered at together.