简体   繁体   中英

Java, Cucumber and Selenium: Problems with navigate().to()

In a setup with Java, Cucumber and Selenium:

I've got the following code which attempts to navigate to a page, and then look for the presence of one or two elements to verify that I am on the page itself.

The problem: About 1 out of 5 times, the test hangs on the page before the target page, apparently looking for (and not finding) the elements before the page navigation is completed.

The error message:

org.openqa.selenium.TimeoutException: Expected condition failed: waiting 
for e2e.navigation.NavigationSteps$$Lambda$260/975372289@202898d7 (tried 
for 40 second(s) with 500 milliseconds interval)

The Cucumber step:

And I navigate to the decision list for the "case"

The step definition:

@When("^I navigate to the decision list for the \"([^\"]*)\"$")
public void INavigateToDecisionListFor(String case) throws Throwable {
    long caseId = ScenarioState.getCaseId(case);

    desicionlistPage.navigateTo(caseId);

    // It looks like this code is executed before the page navigation 
    // (above) is executed, hence making the test hang here looking for 
    // the elements on the
    // target page:

    Browser.Wait().ignoring(WebDriverException.class).until(webDriver -> 
    {
        WebElement enabledButton = null;
        WebElement disabledButton = null;
        try {
            enabledButton = webDriver.findElement(By.id("opprett-
            innstilling-btn"));
        } catch (NoSuchElementException ignore) {  }
        try {
            disabledButton = webDriver.findElement(By.id("opprett-
            innstilling-btn-disabled"));
        } catch (NoSuchElementException ignore) {  }

        return enabledButton != null || disabledButton != null;
    });
}

DecisionListPage.java:

public void navigateTto(long vased) {
    driver.navigate().to(Config.getSimulatedUrl() + "/#/case/" + cased + 
    "/decision/");
}

The URL is correct. I can enter it manually when the test hangs, and then the test continues (to the element verification). So the problem definetely seem to be that the verification is attempted before the navigation is performed.

When troubleshooting, I've tried adding extra waits and replacing driver.navigate.To() with driver.get(), with no luck. It still fails frequently.

However, if I repeat the navigate().to() step, then it seems to work. That is, just do it twice, like this:

driver.navigate().to(Config.getSimulatedUrl() + "/#/case/" + cased + 
    "/decision/");
driver.navigate().to(Config.getSimulatedUrl() + "/#/case/" + cased + 
    "/decision/");

I've run the tests manually 30-40 times, and it hasn't failed with the above solution. But that's just a silly way to do it.

So what I'm wondering about is: The best wait to ensure that the driver.navigate.To() is actually performed before the execution continues? I thought driver.get() was the way to acchieve that, but that fails just as surely.

NB: This code is not written by me, but I'm using it. I'm not sure that I'd do the element verification quite like this myself, but the problem seems to be with the navigation not completing/waiting, and not the checks themselves.

I apologize if the question is unclear, or if I should've checked this or that obvious thing before asking. If so, please tell me and I'll update the question.

UPDATE There is also a link button for navigating to the page. When I use THAT, it seems to work all the time. But this is kind of worse; Why on earth doesn't it work with navigate().to() (unless I do it twice), when it works with the link?

    After reviewing your code, I hope you are using Scenario Outline concept of cucumber to run the same test case with multiple cases like below:

    Scenario Outline:
    When I navigate to the decision list for the "<code>"
    Examples:
    |code|
    |100|
    |200|
    |300|
    |400|
    |500|

    In your code, you are performing navigation and validation whether the expected elements are displaying on the loaded page or not in single step. Instead you can try in this in two steps to overcome navigational issues to the right coded url:

    -- feature file

    Scenario Outline:
    When I navigate to the decision list for the "<code>"
    Then I perform validation on loaded page
    Examples:
    |code|
    |100|
    |200|
    |300|
    |400|
    |500|

    --spec file

     @When("^I navigate to the decision list for the \"([^\"]*)\"$")
     public void INavigateToDecisionListFor(String case) {
           long caseId = ScenarioState.getCaseId(case);
           DecisionListPage.navigerTil(caseId );
     }
     // Above step will navigates you to the specific case page

    @Then("^I perform validation on loaded page"$)
    public boolean performValidation() throws Throwable {

        WebElement enabledButton = null;
        WebElement disabledButton = null;
        try {
            enabledButton = webDriver.findElement(By.id("opprett-
            innstilling-btn"));
        } catch (Exception ignore) {  }
        try {
            disabledButton = webDriver.findElement(By.id("opprett-
            innstilling-btn-disabled"));
        } catch (Exception ignore) {  }

        return enabledButton != null || disabledButton != null;
    }
    // above step will perform validations for you

    --DecisionListPage.java:

    public static void navigerTil(long caseId ) {
        driver.navigate().to(Config.getSimulatedUrl() + "/#/case/" + caseId + 
        "/decision/");
    }

Do these changes in your code and run it once. I hope, this process will resolve this issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM