WebDriverWait is not working - java

I am using Windows 8, IE 10 (java - WebDriver 2.37.0) and I am trying to wait until the element is loaded on the page. I used following code:
WebDriver driver = new FirefoxDriver();
driver.get("http://abc.com");
WebElement myDynamicElement = (
new WebDriverWait(driver, 10).until(
ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
But it's throwing a timeout exception. If I remove this code, it's able to identify the element on the webdriver.
I tried the same code in other browsers as FireFox, Chrome but its still throwing error.
Any help is appreciated.
Thanks

You're assigning that wait to the variable myDynamicElement. If you don't give the WebElement variable something to do, Selenium will throw that timeout exception. If you just want to wait for the element to be present then there is no need to assign it to a WebElement variable.
WebDriver driver = new FirefoxDriver();
driver.get("http://abc.com");
new WebDriverWait(driver, 10).until(
ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
If you need to assign that variable for later use then do something with the element.
WebElement myDynamicElement =
new WebDriverWait(driver, 10).until(
ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
myDynamicElement.isDisplayed();

public static void waitForElementToAppear(Driver driver, By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
}

Related

I can't click on an element

the page is fully loaded and the element is located, but for some reason it can't be clicked, I can't understand why.
My test:
#Test
public void test(){
chromeDriver.get("https://alfabank.ru/currency/");
WebDriverWait wait = new WebDriverWait(chromeDriver, 8);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]")));
WebElement clicking = chromeDriver.findElement(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]"));
clicking.click();
}
Full xpatch it doesn't work either:
WebElement clicking = chromeDriver.findElement(By.xpath("/html/body/div[1]/div/div[6]/div/div/div/div/div[1]/div[1]/button[2]"));
Exception:
org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element is not clickable at point (539, 1199)
None of the existing answer really explain what is their code is about.
Even if you launch the screen in full screen, USD is not in Selenium view port.
Also JS is only recommended when nothing works.
I am doing with Selenium class, actions, please see below :
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.get("https://alfabank.ru/currency/");
boolean b = wait.until(ExpectedConditions.titleIs("Курсы валют — «Альфа-Банк»"));
if (b) {
new Actions(driver).moveToElement(wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div[data-test-id='caption']")))).build().perform();
WebElement clicking = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]")));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", clicking);
}
I use JS click, don't know why cannot click normally.
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]")));
WebElement clicking = driver.findElement(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true); arguments[0].click()", clicking);
Apply scrollIntoView and then click on the USD using JavascriptExecutor.
JavascriptExecutor js = (JavascriptExecutor) driver;
WebDriverWait wait = new WebDriverWait(driver,30);
driver.get("https://alfabank.ru/currency/");
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]")));
WebElement usdoption = driver.findElement(By.xpath("//button[contains(#class, 'j1I7k')]//p[contains(text(), 'USD')]"));
js.executeScript("arguments[0].scrollIntoView(true);", usdoption);
js.executeScript("arguments[0].click();", usdoption);

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);
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
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

Selenium: ElementNotVisibleException while trying to click the element with text as My Account onhttps://www.phptravels.net/

When I tested phptravel website and tried to click on the myaccount link with the below code.
Selenium returns ElementNotVisibleException during the execution. What is the thing that I missed?
Source code
public void login(WebDriver driver) {
driver.navigate().to("https://www.phptravels.net/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/nav/div/div[1]/a")));
// Error on here
myAccount.click();
WebDriverWait myAccountWait = new WebDriverWait(driver, 10);
myAccountWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[#id=\"li_myaccount\"]/ul")));
loginLink.click();
WebDriverWait loginWait = new WebDriverWait(driver, 10);
//loginWait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\\\"loginfrm\\\"]/div[1]/div[5]/div/div[1]/input")));
username.sendKeys("user#phptravels.com");
password.sendKeys("demouser");
loginBtn.click();
}
myAccount webElement is not initialized in your code.
In case you want to click on My account link you can use this :
WebElement myAccount = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#id='collapse']/descendant::ul[3]/li[#id='li_myaccount']/a")));
myAccount.click();
Note that you can't use link Text as that is text nodes .
Modify the code as below:
On your WebDriverWait keep the xpath as below with By type:
By myAccountBy = By.xpath("//ul[#class='nav navbar-nav navbar-right']/ul/li[1]/a");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(myAccountBy));
OR
Hardcode the xpath like below.
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.Xpath("//ul[#class='nav navbar-nav navbar-right']/ul/li[1]/a")));
Then keep the same xpath for myAccount WebElement as below
#FindBy(xpath="//ul[#class='nav navbar-nav navbar-right']/ul/li[1]/a")
public WebElement myAccount;
In short, to click the MyAccount you have to keep this xpath
//ul[#class='nav navbar-nav navbar-right']/ul/li[1]/a
First you need to create WebElement then use elementToBeClickable Expected Condition for the same this way you can resolve the issue
WebElement myAccount = driver.findElement("Your locator");
Now use wait
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(myAccount));
myAccount.click();
Also maximize the browser.
It is always a best practice to add the explicit wait after loading the URL. I am able to click the Account link based on the below modified XPath.
Xpath: //nav//li[#id='li_myaccount']//a
Working Code:
driver.get("https://www.phptravels.net/");
WebDriverWait wait=new WebDriverWait(driver,10);
//wait is added in order to complete the page loading
wait.until(ExpectedConditions.titleContains("PHPTRAVELS"));
driver.findElement(By.xpath("//nav//li[#id='li_myaccount']//a")).click();
To click() on the element with text as My Account instead of visibilityOfElementLocated() you need to induce WebDriverWait through elementToBeClickable() method and you can use the following solution:
Code Block:
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver=new FirefoxDriver();
driver.get("http://www.phptravels.net");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//nav[#class='navbar navbar-default']//li[#id='li_myaccount']/a[normalize-space()='My Account']"))).click();
Browser Snapshot:

Not able to click dropdown

I am a new learner in selenium and try to click on a dropdown to populate list but it keeps on giving me runtime exception:
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException:
Element is not currently visible and so may not be interacted with )
Please help. Below is my code that I am executing.
WebDriver dr=new FirefoxDriver();
dr.get("https://jqueryui.com/selectmenu/");
dr.manage().window().maximize();
dr.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
dr.switchTo().frame(dr.findElement(By.className("demo-frame")));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("speed- menu"))).click();
To click on the Dropdown Select a speed, here is your own code with minimal changes:
System.setProperty("webdriver.gecko.driver", "C:\\your_directory\\geckodriver.exe");
WebDriver dr=new FirefoxDriver();
dr.get("https://jqueryui.com/selectmenu/");
dr.manage().window().maximize();
dr.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
dr.switchTo().frame(dr.findElement(By.className("demo-frame")));
dr.findElement(By.xpath("//*[#id='speed-button']/span[#class='ui-selectmenu-text']")).click();
Let me know if this Answers your Question.
Try This
WebDriver driver = new FirefoxDriver();
driver.get("https://jqueryui.com/selectmenu/");
WebElement DynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("DynamicElement")));
OR
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("yourid")));

StaleElementReferenceException Error on Java- selenium

I am getting StaleElementReferenceException when I run my code for selecting "Buy NOW" from flipkart.com. This is what I have, but its not working for me.
public void SelectItemfromPage(){
WebDriver wd = new FirefoxDriver();
wd.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
wd.get("http://www.flipkart.com");
WebElement element = wd.findElement(By.xpath(".//*[#id='fk-top-search-box']"));
element.sendKeys("moto g");
element.submit();
element.findElement(By.xpath(".//*[#id='products']/div/div[1]/div[1]/div/div[1]/a[1]/img")).click();
element.findElement(By.xpath(".//*[#id='fk-mainbody-id']/div/div[7]/div/div[3]/div/div/div[6]/div/div[3]/div[1]/div/div[2]/div/div[2]/form/input[9]")).click();
}
Your approach is all wrong.
You are saving an WebElement and reusing it, that's not the way to go.
When you save a WebElement in an object, in this case element, the WebElement will become stale whenever the DOM changes.
What you need to do is the following:
WebDriver wd = new FirefoxDriver();
wd.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
wd.get("http://www.flipkart.com");
WebElement element = wd.findElement(By.xpath(".//*[#id='fk-top-search-box']"));
element.sendKeys("moto g");
element.submit();
wd.findElement(By.xpath(".//*[#id='products']/div/div[1]/div[1]/div/div[1]/a[1]/img")).click();
wd.findElement(By.xpath(".//*[#id='fk-mainbody-id']/div/div[7]/div/div[3]/div/div/div[6]/div/div[3]/div[1]/div/div[2]/div/div[2]/form/input[9]")).click();

Categories