In a perfect world, if our automation framework highlights “jankiness” the preferred outcome is that we fix it. However, we don’t live in a perfect world!
I have a preferred hierachy for waiting steps:
No waiting where possible.
Wait for visibility: e.g., waiting for a loading spinner to disappear, or for an interactable element to appear
Wait for an API request: Either to resolve, or to fire.
Network idle: It’s a nice catch-all, but I’ve found it behaves inconsistently across environments.
Expicit wait: (waitForTimeout) this is dead last, because it will eventually fail.
I also prefer to have retries in my tests by default. It’s a crucial distinction in regression runs to know whether a test is flaky or actually failing.