Reputation: 2066
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
Reputation: 2066
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
Reputation: 193148
To send a character sequence to the email element as the the desired element is within an <iframe>
so you have to:
frameToBeAvailableAndSwitchToIt()
.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