3

I wrote automated tests with help of JUnit, Selenium Webdriver (v. 3.141.59) and Chromedriver (v. 2.45).

Firstly, I wrote a login test:

[...]
void loginTest() {
    driver().findElement(By.id("login-button")).click();
    driver().findElement(By.id("name")).sendKeys("mail@xx.com");
    driver().findElement(By.id("password")).sendKeys("password");
    driver().findElement(By.id("send")).click();
    assertTrue(driver().findElement(By.id("logged-in-msg")).isDisplayed());
}

Everything worked fine, all good, test green.

Then I got some more and more complicated and long ids and xpaths I had to use, so I decided to keep tests short and nice and put all my locators in separate class, like this:

public class LocatorsList {
public static final String
        SIGN_IN_BUTTON = "login-button",
        LOG_IN_USERNAME = "name",
        LOG_IN_PASSWORD = "password",
        LOG_IN_BUTTON = "send",
        SUCCESS_MSG = "logged-in-msg";
}

And my test:

[...]
void loginTest() {
    driver().findElement(By.id(SIGN_IN_BUTTON)).click();
    driver().findElement(By.id(LOG_IN_USERNAME)).sendKeys("mail@xx.com");
    driver().findElement(By.id(LOG_IN_PASSWORD)).sendKeys("password");
    driver().findElement(By.id(LOG_IN_BUTTON)).click();
    assertTrue(driver().findElement(By.id(SUCCESS_MSG)).isDisplayed());
}

Then it stopped working. Webdriver sends errors:

org.openqa.selenium.NoSuchElementException: no such element: 
Unable to locate element: {"method":"id","selector":"name"}

As I watched my test going, this element was right there on the page, webdriver even clicked at it as if it wanted to fill the field... but it didn't. Says 'unable to locate element'. I tried to change chromedriver and selenium versions but it didn't help.

  • From the errorlog you have given it looks like driver is able to find the sign in button & clicking it, but failing to find the login_user_name field(as its not able to find the "method":"id","selector":"name"), so can you try adding a little bit of wait in between the steps? – SnR Jan 07 '19 at 04:23
  • Well, I set the timeout for 60 seconds before every step just for sure. It appears that webdriver doesn't even wait that long, after a few seconds of "looking" at this field it quits. – alice-liddell Jan 07 '19 at 04:56
  • Use `Thread.sleep` right after logging in. You need to wait should it work. – mahan Jan 07 '19 at 09:09

2 Answers2

0

This is most probably due to element not present, you need to wait for the element to be loaded. Use

WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated((By.id(LOG_IN_USERNAME))));

After that you can perform the action on that particular element say sendKeys event.

public class Testing {

    public static final String 
    SIGN_IN_BUTTON = "jsid-login-button",
    LOG_IN_USERNAME = "login-email-name",
    LOG_IN_PASSWORD = "login-email-password",
    LOG_IN_BUTTON = "input[type='submit']";

    WebDriver driver;

    @BeforeMethod
    public void setUp() {
        System.setProperty("webdriver.chrome.driver", <driverLocation>);
        driver = new ChromeDriver();
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
        driver.get("https://9gag.com/");
    }

    @Test
    public void demoTest() {
        driver.findElement(By.id(SIGN_IN_BUTTON)).click();
        WebDriverWait wait = new WebDriverWait(driver, 20);
        wait.until(ExpectedConditions.presenceOfElementLocated((By.id(LOG_IN_USERNAME))));
        driver.findElement(By.id(LOG_IN_USERNAME)).sendKeys(<YOUR_EMAIL>);
        driver.findElement(By.id(LOG_IN_PASSWORD)).sendKeys(<YOUR_PASSWORD>);
        driver.findElement(By.cssSelector(LOG_IN_BUTTON)).click();
    }

    @AfterMethod
    public void tearDown() {
        driver.quit();
    }

}
anurag0510
  • 763
  • 1
  • 8
  • 17
  • This also doesn't work. I tried it when wait() alone didn't help. In this case (waiting for element to load) webdriver waits for 120 seconds (I set this much to be sure) and ends test with the same error. Page didn't load anymore for about a minute and it still waited for an element, which it has already found and clicked on. **EDIT** Sorry, not the same error. This time it was "Expected condition failed: waiting for visibility of element located by By.id: name (tried for 120 second(s) with 500 milliseconds interval)" – alice-liddell Jan 07 '19 at 07:28
  • Is your page loaded completely after clicking SIGN_IN_BUTTON? – anurag0510 Jan 07 '19 at 07:43
  • Can you share the page source after clicking SIGN_IN_BUTTON and also page source if LOG_IN_USERNAME was clicked on ? There is a chance the DOM changed. – anurag0510 Jan 07 '19 at 07:51
  • DOM doesn't change a bit after clicking in that field. – alice-liddell Jan 07 '19 at 08:18
  • Could you share the app name so that I can try? – anurag0510 Jan 07 '19 at 08:48
  • It's 9gag.com :D I changed locators a little so example above is clearer. Locators in 9gag aren't always that pretty. – alice-liddell Jan 07 '19 at 10:33
  • @alice-liddell just updated the answer and checked too. Could you confirm the same? – anurag0510 Jan 07 '19 at 11:06
0

If that's honestly the only real change to the code, then could it be as simple as you missing the class name before the string? I.e:

driver().findElement(By.id(LocatorsList.SIGN_IN_BUTTON)).click()

Lovethenakedgun
  • 731
  • 6
  • 22
  • Have you tried logging or printing what the variable SIGN_IN_BUTTON contains just prior to the driver().findElement call? If it resolves to "login-button", then the problem is likely elsewhere. – Lovethenakedgun Jan 07 '19 at 08:33