1

So I understood fluent and explicit waits but I could never get the implicit statements to work in the past. I managed to not deal with them using explicits but I then designed a test that was fairly simple but it would only work with Thread.sleep and I absolutely HATE that method and try to avoid it at all costs. So I attempted the implicit wait function again... fail.

The code below with Thread.Sleep works as intended and is great

package myPackages;

import java.util.concurrent.TimeUnit;

//  Unit test testing the Main User Drop Down Menu
//  This tests the following:
//      - changing status to Online, Away, Busy, Invisible via Left menu 
//      - Going to Settings
//      - Logging out

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class statusTest {

  private static WebDriver driver = new SafariDriver();

  public static String HOME_URL = "http://localhost:3000";
  public static String currentUserStatus;

  private static By usernameOrEmailFieldLocator = By.id("emailOrUsername");
  private static By passwordFieldLocator = By.id("pass");
  private static By loginButtonLocator = By.cssSelector("button.button.primary.login");

  private static By openMenuLocator = By.cssSelector("span.arrow.bottom");

  private static By onlineButtonLocator = By.cssSelector("button.status.online");
  private static By awayButtonLocator = By.cssSelector("button.status.away");
  private static By busyButtonLocator = By.cssSelector("button.status.busy");
  private static By invisibleButtonLocator = By.cssSelector("button.status.offline");
  private static By userStatus = By.className("thumb");


  @BeforeClass
  public static void beforeClass() {
    driver.get(HOME_URL);
    driver.findElement(usernameOrEmailFieldLocator).sendKeys("adrian");
    driver.findElement(passwordFieldLocator).sendKeys("adrian");
    driver.findElement(loginButtonLocator).click();
  }

  @Before
  public void before() throws Exception {
    Thread.sleep(100);
    new WebDriverWait(driver, 3).until(ExpectedConditions.presenceOfElementLocated(openMenuLocator)).click();
    Thread.sleep(100);
    new WebDriverWait(driver, 3).until(ExpectedConditions.presenceOfElementLocated(onlineButtonLocator)).click();
  }

  @AfterClass
  public static void doEnd() {
    driver.quit();
  }

  private static void changeStatusTo(By statusLocator) throws Exception {
    Thread.sleep(100);
    new WebDriverWait(driver, 3).until(ExpectedConditions.presenceOfElementLocated(statusLocator)).click();
    Thread.sleep(100);
    currentUserStatus = driver.findElement(userStatus).getAttribute("data-status");
  }

  @Test
  public void setAway() throws Exception {
    changeStatusTo(awayButtonLocator);
    Assert.assertEquals("away", currentUserStatus);
  }

  @Test
  public void setOnline() throws Exception {
    changeStatusTo(onlineButtonLocator);
    Assert.assertEquals("online", currentUserStatus);
  }

  @Test
  public void setBusy() throws Exception {
    changeStatusTo(busyButtonLocator);
    Assert.assertEquals("busy", currentUserStatus);
  }

  @Test
  public void setInvisible() throws Exception {
    changeStatusTo(invisibleButtonLocator);
    Assert.assertEquals("invisible", currentUserStatus);
  }

}

but when I end up trying to use the implicit (such as below) it doesn't work. I ensure to declare it once (in this case the @beforeclass) right after the driver is declared. The tests would fail within the Before class. I included the trace stack at the very bottom on this page:

package myPackages;

import java.util.concurrent.TimeUnit;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class statusTest {

    private static WebDriver driver = new SafariDriver();

    public static String HOME_URL = "http://localhost:3000";
    public static String currentUserStatus;

    private static By usernameOrEmailFieldLocator = By.id("emailOrUsername");
    private static By passwordFieldLocator = By.id("pass");
    private static By loginButtonLocator = By.cssSelector("button.button.primary.login");

    private static By openMenuLocator = By.cssSelector("span.arrow.bottom");

    private static By onlineButtonLocator = By.cssSelector("button.status.online");
    private static By awayButtonLocator = By.cssSelector("button.status.away");
    private static By busyButtonLocator = By.cssSelector("button.status.busy");
    private static By invisibleButtonLocator = By.cssSelector("button.status.offline");
    private static By userStatus = By.className("thumb");


    @BeforeClass
    public static void beforeClass(){
        driver.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS);
        driver.get(HOME_URL);
        driver.findElement(usernameOrEmailFieldLocator).sendKeys("adrian");
        driver.findElement(passwordFieldLocator).sendKeys("adrian");
        driver.findElement(loginButtonLocator).click();
    }

    @Before
    public void before() throws Exception {
        driver.findElement(openMenuLocator).click();
        driver.findElement(onlineButtonLocator).click();
    }

    @AfterClass
    public static void doEnd() {
        driver.quit();
    }

    private static void changeStatusTo(By statusLocator) {
        driver.findElement(statusLocator).click();
        currentUserStatus = driver.findElement(userStatus).getAttribute("data-status");

    }

    @Test
    public void setAway() {
        changeStatusTo(awayButtonLocator);
        Assert.assertEquals("away", currentUserStatus);
    }

    @Test
    public void setOnline() {
        changeStatusTo(onlineButtonLocator);
        Assert.assertEquals("online", currentUserStatus);
    }

    @Test
    public void setBusy() {
        changeStatusTo(busyButtonLocator);
        Assert.assertEquals("busy", currentUserStatus);
    }

    @Test
    public void setInvisible() {
        changeStatusTo(invisibleButtonLocator);
        Assert.assertEquals("invisible", currentUserStatus);
    }

}

org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters. (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 999 milliseconds For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html Build info: version: 'unknown', revision: '1969d75', time: '2016-10-18 09:43:45 -0700' System info: host: 'Adrians-iMac.local', ip: '10.0.2.15', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.1', java.version: '1.8.0_111' Driver info: org.openqa.selenium.safari.SafariDriver Capabilities [{applicationCacheEnabled=true, rotatable=false, databaseEnabled=true, handlesAlerts=true, version=12602.2.14.0.5, cleanSession=true, platform=MAC, nativeEvents=true, locationContextEnabled=false, webStorageEnabled=true, browserName=safari, javascriptEnabled=true, cssSelectorsEnabled=true}] Session ID: DADE0351-039B-4C06-BC65-05FB90E08202 *** Element info: {Using=css selector, value=span.arrow.bottom} at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:635) at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:368) at org.openqa.selenium.remote.RemoteWebDriver.findElementByCssSelector(RemoteWebDriver.java:465) at org.openqa.selenium.By$ByCssSelector.findElement(By.java:430) at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:360) at myPackages.statusTest.before(statusTest.java:53) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Potion
  • 785
  • 1
  • 14
  • 36

1 Answers1

1

Use TimeUnit.SECONDS in your implicit waits instead of milliseconds. Quick glance through your code indicates that you have used 100 milliseconds in implicit wait which is very nominal compared to 3 seconds assigned in explicit wait.

 driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//waits for 3 seconds

Note:unit for explicit wait is in seconds.

 new WebDriverWait(driver, 10) //will wait for 10 seconds 

1000ms=1s

You should be using 3000ms in implicit wait if timeunit HAS to be in milliseconds.

prithvi394
  • 221
  • 1
  • 6
  • I understand that if I were to use an implicit of 3 seconds with a WebDriverWait of 10 seconds then it would run about 13 seconds give or take depending on the WebDriverWait correct? So anyways I changed my code to be 3 seconds and it still didnt seem to work. Same trace stack – Potion Dec 27 '16 at 17:28
  • You need not use implicit wait and explicit waits together. Moreover implicit and explicit waits do not add up!Once implicit wait is declared, browser will wait for x seconds before throwing an exception. – prithvi394 Dec 27 '16 at 17:33
  • So I shouldnt even with implicit waits and just use my original code? – Potion Dec 27 '16 at 17:45
  • You need not use implicit wait and explicit waits together. Moreover implicit and explicit waits do not add up!The larger wait overrides the smaller wait(Explicit overrides implicit in most cases) Once implicit wait is declared, browser will wait for x seconds before throwing an exception.You may need to increase the implicit wait if your code has to work although I suggest you to use explicit wait for these situations! – prithvi394 Dec 27 '16 at 18:09
  • Implicit wait is generally declared during driver declaration and is carried throughout the life of driver instance.Whereas explicit wait is used for situations when you need driver to wait more duration than specified in the implicit wait. – prithvi394 Dec 27 '16 at 18:13
  • Okay I understand. But im my working code (the first one) why must I put thread.sleep for an explicit wait? It doesnt make sense, it breaks the purpose of it – Potion Dec 27 '16 at 18:32
  • I don't think you do need to use Thread.Sleep there, your explicit wait may just need to be a little longer. But you should also just be able to use the implicit wait, assuming you set it to a longer timeframe. – Josh Dec 27 '16 at 21:31