0

I am having a really hard time with the following issue. I am trying to navigate through some web pages that have various inputs (text boxes/dropdowns/buttons) followed by a continue button at the bottom to move onto the next screen. My tests frequently fall over because they can't always locate the first element in order to interact with it.

As far as I'm aware the page doesn't do any fancy AJAX post loading or anything, so once the page has loaded then Webdriver should be able to locate every element.

My code:

FRAMEWORK

public static void WaitOnPageForXPathClickable(string selector)
    {
        new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable((By.XPath(selector))));
    }

TEST CASE

Utilities.WaitOnPageForXPathClickable("the xpath of the continue button and checks that it is clickable");
Driver.Instance.FindElement(By.XPath("the xpath of the first button that I want to click")).Click();

Do I need to try and include a function to ensure that the page is fully loaded before test execution? I am confused about this because I have read that Selenium already waits for the page to load by default. I would have thought that waiting for one element (the continue button) to be clickable should mean that all other elements are ready by then too? I really want to avoid having to wait for every single element before clicking it.

sad muso
  • 91
  • 8
  • And in your test case are you passing an xpath? it's like your code is failing to find the element *"put an xpath here"*. – derloopkat Dec 08 '17 at 13:52
  • Yeah, I replaced that in the example to explain what I'm looking for. In the code I'm using actual xpaths – sad muso Dec 08 '17 at 14:09
  • Ahh, in that case need to check that xpath is correct and element is visible. Try using the page manually and follow same steps till the element appears. Then open inspection tool and test that xpath. https://stackoverflow.com/questions/22571267/how-to-verify-an-xpath-expression-in-chrome-developers-tool-or-firefoxs-firebug – derloopkat Dec 08 '17 at 14:13
  • Thanks - I know that the xpath is correct though because the test only fails intermittently. That's what is leading me to believe that it's a synchronisation issue. – sad muso Dec 08 '17 at 14:21
  • "they can't always locate the first element in order to interact with it" --- is this the textboxes,dropdowns etc or the continue button? There is a caveat for page to be completely loaded in selenium by a click() event. It may not wait for the page to be loaded depending on the event type such as native event. - https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/WebElement.html#click-- – Grasshopper Dec 08 '17 at 14:27
  • The element in this example is a button: `` – sad muso Dec 08 '17 at 14:47
  • @sadmuso You are making things much more complicated by **waiting** for the `Continue` button `Utilities.WaitOnPageForXPathClickable("the xpath of the continue button and checks that it is clickable");` **but** trying to **click()** on the `First` Button `Driver.Instance.FindElement(By.XPath("the xpath of the first button that I want to click")).Click();` – undetected Selenium Dec 08 '17 at 14:59

2 Answers2

0

You have made things much more complicated by waiting for the Continue Button Utilities.WaitOnPageForXPathClickable("the xpath of the continue button and checks that it is clickable"); where as in the next step trying to click() on the First Button Driver.Instance.FindElement(By.XPath("the xpath of the first button that I want to click")).Click();

Test Scenario:

Ideally your Test Scenario should have been :

TEST CASE:

Utilities.WaitOnPageForXPathClickable("the xpath of the first button that I want to click");
Driver.Instance.FindElement(By.XPath("the xpath of the first button that I want to click")).Click();

FRAMEWORK:

public static void WaitOnPageForXPathClickable(string selector)
{
    IWebElement element = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable((By.XPath(//label[@class='replaced-input-label replaced-input-label--radio']))));
    elementClick();
}
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • @sadmuso Did you try out my Answer? Did you face any error? Can you update the error stack trace? – undetected Selenium Dec 08 '17 at 14:31
  • But my test doesn't fail when checking whether the Continue button is clickable; it fails when it tries to click the first element on the page (a button which is within the viewport), so my test is as follows: check that Continue button outside of viewport is clickable - passes, find first button on page via xpath and click it - claims it cannot find the element but it exists! – sad muso Dec 08 '17 at 14:53
  • The reason I did this was because that Continue button is present on every page so I could use the same line of code everywhere. Also, I thought that checking the last button on the page would somehow give me a better chance of all elements being back (making the assumption that they load top to bottom which could be wrong of course) – sad muso Dec 08 '17 at 15:48
  • @sadmuso No, you shouldn't do that. Check out my answer & let me know the status. – undetected Selenium Dec 08 '17 at 15:50
  • Here is my updated code: `Utilities.WaitOnPageForXPathVisible("(//INPUT[@size='30'])[1]"); Driver.Instance.FindElement(By.XPath("(//INPUT[@size='30'])[1]")).SendKeys("Test");` This is using the following: `public static void WaitOnPageForXPathVisible(string selector) { new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementIsVisible((By.XPath(selector)))); }` I just ran this and it failed THREE times at the point where it is waiting for it to be visible, then passed two times! What is happening!? – sad muso Dec 09 '17 at 21:03
0

Can you please share html, have you tried with Visible instead of Clickable

public static void WaitOnPageForXPathClickable(string selector)
{
    new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementIsVisible((By.XPath(selector))));
}

You can wait for the page to be fully loaded with something like:

        public void WaitForPageToBeFullyLoaded(int timeSpan)
    {
        new WebDriverWait(Driver, TimeSpan.FromSeconds(timeSpan)).Until(
            d => ((IJavaScriptExecutor) d).ExecuteScript("return document.readyState").Equals("complete"));
    }

You can check for displayed or Enabled element too.

  • I just tried ElementToBeVisible but ExpectedConditions doesn't contain that definition - have it been deprecated or is it from another syntax? I can find ElementIsVisible - guess that's it; I'll try it. – sad muso Dec 08 '17 at 14:14
  • UPDATE: Tried changing ElementToBeClickable to ElementIsVisible but still no luck - test still failing because it can't find the xpath I am looking for. But only sometimes - just tried it twice and the second time it worked. It MUST be a timing issue; surely? – sad muso Dec 08 '17 at 14:56
  • I haven't tried the page fully loaded idea yet - maybe that will do the trick – sad muso Dec 08 '17 at 14:57