1

EDIT: I have narrowed the problem to its possible source see Update 2 and you can skip the intro.

My issue is that selenium "thinks" it has clicked a link when the link click was never actually executed. The problem is due to a timing issue for InternetExplorer as Firefox doesn't seem to have this same issue (at least as often).

The issue occurs when I am on a particular page, open a popupdialog widget on that page, than close it and than try to continue to navigate.

Sample code:

//Already navigated to Myphotospage.
Account.MyPhotosPage.isLoaded();//Just to show its been loaded not required code.
Account.MyPhotosPage.ButtonUploadPhoto.click(); //Shows widget to user
Account.MyPhotosPage.DialogUploadPhoto.File.setText(Directory)//Do stuff...
Account.MyPhotosPage.DialogUploadPhoto.ButtonOK.click(); //Close dialog
Assert.IsTrue(Account.MyPhotosPage.isLoaded()); //Check that the page is still loaded

Account.MyPhotosPage.Menu.MyContacts.click(); //Navigate to a new page.
//FAILS THIS NEXT LINE SINCE PREVIOUS CLICK DID NOT ACTUALLY CLICK Though
//Selenium acts as if it did.
Assert.IsTrue(Account.MyContactsPage.isLoaded()); //Checks that new page is laoded

The main page contains dynamic images which means user can upload as many as they want so the elements id can dynamically change. The dialog uploads a new image to the page. I think this contributes to the slower loading/unloading times.

Currently I wait between each IWebElement reference using WebDriverWait timeout of 10 seconds:

_WAIT.Until(ExpectedConditions.ElementIsVisible); //PDEUDO Code. My code is slightly different.

Here is how the current execution behaves.

  1. It navigates to page.
  2. It popups the dialog
  3. It closes Dialog
  4. It immediately states the page is loaded though the "widget" could still actually be open or unloading itself. This can be seen with Console.WriteLines being written to output before the widget has fully closed.
  5. It thinks the page is loaded.
  6. It waits for IWebElement to be visible and executes the click command when visible before widget is unloaded or page is actually fully rendered. (Account.MyPhotosPage.Menu.MyContacts.click())

Because it thinks the element is visible and clicks it early, it doesn't actually navigate to the new page. Though selenium thinks it clicked the element successfully.

If I add a thread wait it fixes the problem.

...
Account.MyPhotosPage.DialogUploadPhoto.ButtonOK.click(); //Close dialog
Thread.Sleep(5 seconds);
...
Account.MyPhotosPage.Menu.MyContacts.click()//Navigate to new page

Summary: The dialog box makes selenium think the backpage isLoaded or that an element was clicked even though it was not registered. So selenium C# code acts as if the element was clicked on the main page while the widget still has focus or unloading (closing).

So increasing wait times does not fix the issue as it thinks the elements ARE visible and were clicked even though the browser did not register it. But by adding the System wait it has more time to load the page (or unload the widget) allowing the functions to work.

Design Notes: If you are interested this may help clarify my design approach.

I go into more detail in a response on this post: https://sqa.stackexchange.com/a/13579/11972

In short I define the main page as follows.

public MyDialog;
public MyPhotosPage()
        {
            PageFactory.InitElements(_DRIVER, this); 
            MyDialog = new MyDialog(); //PageFactory is executed in the constructor for the dialog page object.
}

Browser: InternetExplorer 11 FireFox seems to work more frequently.

Goal: I would like it to fully load without adding System waits. Any ideas? I prefer using some type of explicit waits. Have not tried using Driver implicit waits.

UPDATE Updated for more information.

My current wait strategy.

while (ignoredException)
            {
                try
                {
                    PageObject._WAIT.Until(d => visibility(element));
                    ignoredException = false;
                }
                catch (StaleElementReferenceException)
                {
                    //Ignored Exception
                }
                catch (NoSuchElementException)
                {
                    //Ignored Exception
                }

                catch (WebDriverTimeoutException e)
                {
                    //Timeout Exception
                    throw new UnabletoFindElementException(e.Message + " Element Locator: " + tag + "  >>>>>>>>  " + e.InnerException);
                }
                catch
                {
                    //Unexpected exception
                    //Rethrow same exception.
                    throw;
                }

My visibility method was adapted from ExpectedConditions.ElementIsVisible (cs file)

 try
        {
            //Checks that the element is in the DOM by accessing its attributes.
            iwe.GetAttribute("");
            //checks that the element is visible. An element can be visible but not currently in the DOM (such as popup dialogs) which is why I added trying to access the IWebElement.
            if (iwe.Displayed)
            {
                return iwe;
            }
            return null;
        }
            // It internally Throws a NoSuchElementException if the element does not exist. Return null to the user for the Wait.Until() function.
        catch (NoSuchElementException)
        {
            return null;
        }

The issue I am having the click method actually "passes" the wait function even though it has not actually been clicked so the browser recognizes it. this same issue can be seen manually when you try to click a link before the page is fully loaded. Sometimes it will not register that mouseclick because internet is going slow. (At least I have seen this in the past).

Update 2: Issue identified I have narrowed the problem further.

I get random errors like Nullreference or StaleElementException (element no longer exists). What is happening is in the widget when I click submit, it begins unloading the dialog and refocuses on the main page. I noticed it does a quick refresh of the page.

So I would begin my code and it would "access" the page elements and randomly fail on different lines of code when the page begins the refresh. So the WaitForElement method passes but than fails later during the refresh since the elements no longer exist in the DOM for a short period.

I guess my only way to fix this is to add System waits (which I hate) as I don't want my test cases to handle this error on the front. To give the page enough time to refresh.

This could explain why the link "clikc" doesnt work as it has not refreshed its state so it ignores it until after the refresh.

1 Answer 1

1

I like the method that is used by the conversion from Selenium IDE to Selenium C# personally, which is as follows:

        for (int second = 0;; second++) {
            if (second >= 60) Assert.Fail("timeout");
            try
            {
                if (IsElementPresent(By.Id("blargh")"))) break;
            }
            catch (Exception)
            {}
            Thread.Sleep(1000);
        }

This gives full control over the loop, what happens when it can't find it and allows you to build in logic to try and manage it in the case of a failure with ease.

1
  • I had a response to your comment but I decided to add it in the OP so it could be read easier. This answer is not a bad answer just doesn't fix my current issue. Also I would prefer to stay away from using By locators. Currently all my code is PageFactory objects. No By locators exist. However if it would fix my issue I am more willing to try it.
    – Tyson
    Commented Jun 24, 2015 at 15:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.