WebdriverIO & Java - org.openqa.selenium.NoSuchElementException in IFrame

I'm facing an exception (org.openqa.selenium.NoSuchElementException) when I try to get element "email". Since I just started playing with WebDriver I'm probably missing some important concept about those race conditions.

WebElement login = driver.findElement(By.id("login"));
login.click();
WebElement iFrame = driver.findElement(By.id("iFrame"));
driver.switchTo().frame(iFrame);
WebElement email = driver.findElement(By.id("email"));
email.sendKeys(USERNAME);

Few things that I've tried but with no success:

Set an implicitly wait:

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

Create a WebDriverWait:


WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement login = driver.findElement(By.id("login"));
login.click();
WebElement iFrame = driver.findElement(By.id("iFrame"));
driver.switchTo().frame(iFrame);
WebElement email = wait.until(presenceOfElementLocated(By.id("email"))); 
// and WebElement email = wait.until(visibilityOf(By.id("email"))); 
email.sendKeys(USERNAME);

Create a FluentWait:

WebElement login = driver.findElement(By.id("login"));
login.click();
WebElement iFrame = driver.findElement(By.id("iFrame"));
driver.switchTo().frame(iFrame);
Wait<WebDriver> wait = new FluentWait<>(driver)
        .withTimeout(Duration.ofSeconds(30))
        .pollingEvery(Duration.ofSeconds(5))
        .ignoring(NoSuchElementException.class);

WebElement email = wait.until(d ->
        d.findElement(By.id("email")));
email.sendKeys(USERNAME);

The only way I managed to make it work was using the old and good Thread.sleep() (ugly as well)

WebElement login = driver.findElement(By.id("login"));
login.click();
WebElement iFrame = driver.findElement(By.id("iFrame"));
driver.switchTo().frame(iFrame);
try {
    Thread.sleep(5000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
WebElement email = driver.findElement(By.id("email"));
email.sendKeys(USERNAME);

Upvotes: 0

Views: 181

Answers (2)

It turns out that the code is ok, but Chrome driver 78 linux 64 bits is messed up. I've tried with Firefox (geckodriver-0.26.0) and it worked like a charm.

Thanks for the help @DebanjanB

Upvotes: 0

undetected Selenium
undetected Selenium

Reputation: 193148

To send a character sequence to the email element as the the desired element is within an <iframe> so you have to:

  • Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt().
  • Induce WebDriverWait for the desired elementToBeClickable().
  • You can use the following Locator Strategies

    driver.findElement(By.id("login")).click();
    new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("iFrame")));
    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.id("email"))).sendKeys(USERNAME);
    

Here you can find a relevant discussion on Ways to deal with #document under iframe

Upvotes: 1

Related Questions