microsoft / WinAppDriver

Windows Application Driver
MIT License
3.69k stars 1.4k forks source link

Explicit wait could not locate the element in "Save As" dialog #1293

Open persephonecmx opened 4 years ago

persephonecmx commented 4 years ago

I have a test script which is supposed to click a button and save the result file. Initially, I used the fixed delay time for the "Save As" dialog to open, the code is as following and it works fine. image

For the next step, I feel the delay time is too long, so that I would like to introduce the explicit wait. The code is as following `public void WaitUntil(string id) {

        int currentAttempts = 0;
        int maxAttempts = 10;
        bool isPresent = false;

        while (currentAttempts < maxAttempts)
        {
            Console.WriteLine("id: {0}, attempt: {1}", id, currentAttempts);

            Thread.Sleep(1000);

            try
            {
                isPresent = session.FindElementsByAccessibilityId(id).Count > 0;
            }

            catch
            {
                isPresent = false;
            }

            if (isPresent == true)
            {
                currentAttempts = 0;
                Console.WriteLine("found id: {0}", id);
                break;
            }

            else
            {
                Console.WriteLine("not found id: {0}", id);
                currentAttempts++;
            }
        }
    }`

However, it always shows the id is not found although the "Save As" dialog is open. image

Does anyone have any ideas about how to solve it please?

anunay1 commented 4 years ago

This is how I have implemented it:

 public WindowsElement WaitForObject(Func<WindowsElement> element, int timeout)
        {
            var wait = new DefaultWait<WindowsDriver<WindowsElement>>(driver)
            {
                Timeout = TimeSpan.FromSeconds(timeout),
                PollingInterval = TimeSpan.FromSeconds(1)
            };

            wait.IgnoreExceptionTypes(typeof(WebDriverException));
            wait.IgnoreExceptionTypes(typeof(InvalidOperationException));
            wait.IgnoreExceptionTypes(typeof(StaleElementReferenceException));
            wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
            wait.IgnoreExceptionTypes(typeof(NotFoundException));
            wait.IgnoreExceptionTypes(typeof(WebException));

            WindowsElement waitElement = null;

            wait.Until(driver =>
            {
                waitElement = element();
                Logger.Logger.LogInfo("Wait completed for the object");
                return waitElement != null && waitElement.Enabled && waitElement.Displayed;
            });

            return waitElement;
        }

you can use it this way:

WaitForObject( () => session.FindElementsByAccessibilityId(id),3)
naeemakram commented 4 years ago

A five seconds display is nothing, it is also keeping your code simple. The more complex your test automation scripts become the more flaky they are(mostly).

persephonecmx commented 4 years ago

Thank you @anunay1 , I tried your code and set the timeout to 15s, however, I still got the error message as shown below.

Message: Test method AutoRun.Main.Main_Test threw exception: OpenQA.Selenium.WebDriverTimeoutException: Timed out after 15 seconds ---> OpenQA.Selenium.WebDriverException: The HTTP request to the remote WebDriver server for URL http://127.0.0.1:4723/session/10240672-1ABA-4D55-8DCF-98FD3DAEC3BB/elements timed out after 60 seconds. ---> System.Net.WebException: The request was aborted: The operation has timed out.

The dialog is open within 2s, but it could not locate the element even after 15s.

anunay1 commented 4 years ago

Is it part of the same tree in inspect.

anunay1 commented 4 years ago

Thank you @anunay1 , I tried your code and set the timeout to 15s, however, I still got the error message as shown below.

Message: Test method AutoRun.Main.Main_Test threw exception: OpenQA.Selenium.WebDriverTimeoutException: Timed out after 15 seconds ---> OpenQA.Selenium.WebDriverException: The HTTP request to the remote WebDriver server for URL http://127.0.0.1:4723/session/10240672-1ABA-4D55-8DCF-98FD3DAEC3BB/elements timed out after 60 seconds. ---> System.Net.WebException: The request was aborted: The operation has timed out.

The dialog is open within 2s, but it could not locate the element even after 15s.

Is it a custom dialog box can you also share what is shown in inspect

persephonecmx commented 4 years ago

Hi @anunay1 , the screenshot is as shown below. The dialog is open and the yellow highlighted area is available, but it shows could not locate the element. image

Furthermore, I added the fixed delay and the explicit wait into the same loop. This is the log for fixed delay (works fine) image

This is the log for explicit delay (error occurs) image