Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium WebDriver reliable tests

I know that this question was asked many times before, but I still couldn't find a solution that works for me. When I run my tests with Selenium WebDriver most of the times they fail with "NoSuchElementException". I tried using Explicit and Implicit Waits but nothing seems to work. So, is there any other way besides using Waits in which I can make my tests more reliable?

I'm using selenium-java-2.31.0 with FirefoxDriver. Below are some samples of code I tried to make my tests more reliable:

public void waitAndClickElement(WebDriver driver, final By selector) {
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(50, TimeUnit.SECONDS)
                .pollingEvery(5, TimeUnit.SECONDS)
                .ignoring(NoSuchElementException.class);
        WebElement elementToClick = wait
                .until(new Function<WebDriver, WebElement>() {
                    public WebElement apply(WebDriver driver) {
                        return driver.findElement(selector);
                    }

                });
        waitForElementVisible(driver, selector);
        elementToClick.click();
         }

..and this:

public WebElement waitForElementPresent(WebDriver driver, final By selector){
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(70, TimeUnit.SECONDS)
            .pollingEvery(5, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);
    WebElement elementToClick = wait
            .until(new Function<WebDriver, WebElement>() {
                public WebElement apply(WebDriver driver) {
                    return driver.findElement(selector);
                }
            });
    return elementToClick;

    } 

...and this:

WebDriverWait wait = new WebDriverWait(driver, 50);
WebElement user_name = wait.until(visibilityOfElementLocated(By.xpath("//*@id='userName']")));

...and this:

driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);

...and finally one of the tests that I try to make more reliable:

@Test
public void test1{
 waitAndClickElement(driver, By.xpath("//*[@id='linkLogIn']"));
        waitForElementPresent(driver, By.xpath("//*[@id='userName']")).sendKeys("name");
        waitForElementPresent(driver, By.xpath("//*[@id='inputEmail']")).sendKeys("[email protected]");
        waitForElementPresent(driver,By.xpath("//*[@id='resetPassword']")).click();
        assertTrue(isElementPresent(By.xpath("//*[@id='moduleMain']")));

}

Thank you!

like image 989
Ela Avatar asked Nov 03 '22 00:11

Ela


1 Answers

Try below custom method. It works fine for me,

public boolean waitForElementToBePresent(By by, int waitInMilliSeconds) throws Exception
    {
        WebDriver driver = getDriver();
        int wait = waitInMilliSeconds;
        int iterations  = (wait/250);
        long startmilliSec = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++)
        {
            if((System.currentTimeMillis()-startmilliSec)>wait)
                return false;
            List<WebElement> elements = driver.findElements(by);
            if (elements != null && elements.size() > 0)
                return true;
            Thread.sleep(250);
        }
        return false;
    }

Use it like,

waitForElementToBePresent(By.id("linkLogIn", 5000);
driver.findElement(By.id("linkLogIn")).click(); 
like image 156
user2087450 Avatar answered Nov 15 '22 13:11

user2087450