Tuesday, 15 October 2013

"Wait" for the element to be ready/visible in Web page when automating functional tests

When coding to automate functional tests for web applications, I find that it is always an issue when waiting for the Web element to be ready and be accessed. I think the challenge here is the waiting time is really various as it depends on the response of the browser in different environment. No one knows how long exactly an element will be available on the page for accessing.

In Selenium, we use WebDriverWait and there are many ExpectedConditions we can choose from in Java. However, this approach does not work in many occasions based on the context. It is not complete guarantee that the element would be waited till the expected the condition meets and becomes accessible. Moreover, the wait will immediately throw error if the locator of the element is evaluated as read-only at the time. So the entire wait process will be terminated.

In Coded UI, we can use UITestControl and its related wait functions to wait until the element is ready to be accessed. However, it does not work every time, either. Moreover, if using IWebElement, there are no such waiting methods available.

With Thread.Sleep() method, we could force the wait in fixed timeframe. However, it is not efficient enough and it is not 100% guaranteed that the fixed wait is long enough.

So at the end, I go for the customized way of waiting and it is not perfect, either. But it should solve most of the issues.

public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds) {
            IWebElement element = null;
            bool found = false;                      

            do {
                try {
                    element = driver.FindElement(by);                    
                    found = true;
                } catch (Exception e) {
                    throw e;
                }

                if (!found) {
                    Thread.Sleep(1000);
                }

                timeoutInSeconds--;
            } while (timeoutInSeconds > 0 && !found);
                     
            return element;
        }

Note that the parameter of timeoutInSeconds is the time of trying to wait for the element to be available but not the time has to be waited in this call. So if the element is available before the timeout, it will be returned.

Based on this method, we can then write more customized methods (if necessary) that to add conditions of waiting. I guess this approach would sort of guarantee that an element will be accessed in the most efficient way.

No comments: