I'm unable to click on an element within a list, once i have clicked on the dropdown list?
Method I have created which Doesn't work.
public static void waitForTextToAppearAndClick(WebDriver driver, WebElement element, String textToAppear) throws InterruptedException{
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOf(element));
WebElement locator = element;
locator.click();
WebElement textToClick = driver.findElement(By.linkText(textToAppear));
wait.until(ExpectedConditions.elementToBeClickable(textToClick));
textToClick.click();
}
Using thread.sleep seems to works but I don't want to use this method, can anybody recommend a way to wait and click on a specific text element once I have clicked on the primary button?
public static void waitForTextToAppearAndClick(WebDriver driver, WebElement element, String textToAppear) throws InterruptedException{
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOf(element));
WebElement locator = element;
locator.click();
Thread.sleep(3000);
driver.findElement(By.linkText(textToAppear)).click();;
}
Please note I need to click on BBQ Sauce, the thread.sleep() is successful when needing to click on BBQ Sauce
Thanks your for help
Use your own implementation of FluentWait in order to wait until text is present after your click:
Wait wait = new FluentWait<>(this.driver)
.withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
.pollingEvery(500, TimeUnit.MILLISECONDS)
.ignoring(StaleElementReferenceException.class)
.ignoring(NoSuchElementException.class)
.ignoring(ElementNotVisibleException.class);
WebElement foo = wait.until(new Function() {
public WebElement apply(WebDriver driver) {
return element.getText().length() > 0;
}
});
all thanks for your help the following method seems to of done the trick:
public static void waitForTextToAppearAndClick(WebDriver driver, WebElement element, String textToAppear) throws InterruptedException{
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOf(element));
WebElement locator = element;
locator.click();
wait.until(ExpectedConditions.elementToBeClickable(By.linkText(textToAppear)));
driver.findElement(By.linkText(textToAppear)).click();
}
Related
In Java, Selenium, you can wait until a text is present in a webelement (with a WebDriverWait):
wait.until(ExpectedConditions.textToBePresentInElement(webelement, expectedMessage));
However, what do you do when you don't want just expectedMessage to be present in the element (= expectedMessage being a substring of webelement.getText()), but to be the exact text of the webelement (=expectedMessage being the same string as webelement.getText())?
Selenium does provide the function:
wait.until(ExpectedConditions.textToBe(locator, expectedMessage));
but when you have gathered webelements by the locators with #FindBy in your page class, it's awkward to make the locators again directly accessible to test classes.
How can this be solved?
You can create your own ExpectedCondition:
public static ExpectedCondition<Boolean> waitForTextInElementEquals(WebElement elm, String text) {
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
String elementText = elm.getText();
return elementText.equals(text);
} catch (StaleElementReferenceException var3) {
return null;
}
}
public String toString() {
return String.format("text ('%s') to be present in element %s", text, elm);
}
};
}
Which you can use just like the ExpectedConditions already in WebDriverWait:
WebDriverWait wait = new WebDriverWait(WebDriver, 30, 1000);
wait.until(waitForTextInElementEquals(foo, bar));
There's another simpler solution:
WebDriverWait wait = new WebDriverWait(webdriver, waitForElementTimeout).until(ExpectedConditions.attributeToBe(webelement, "text", expected));
Tested with selenium 3.8.1.
I'm trying to use FluentWait instead of sleep and this is my first practice. First of all and most importantly am I doing it right at all? Secondly I got through two elements so I thought it kind of works (PaymentMethod button and CheckOut button). Before I implemented FluentWait it wouldn't find them. And finally it won't find the third(backToDesktop button) element. Keeps throwing Element not visible, although I added the wait.ignore(ElementNotVisibleExcecption.class).
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(login.getDriver());
wait.withTimeout(5, TimeUnit.SECONDS);
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
wait.ignoring(NoSuchElementException.class);
wait.ignoring(ElementNotVisibleException.class);
WebElement paymentMethod = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return login.getDriver().findElement(By.xpath("//*[#id='paymentMethodHolder']/div[1]/div[1]/button"));
}
});
paymentMethod.click();
System.out.println("FOUND PAYMENTMETHOD BUTTON");
WebElement checkOut = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return login.getDriver().findElement(By.xpath("//*[#id='checout-footer-buttons']/button[2]"));
}
});
checkOut .click();
System.out.println("FOUND KINNITA BUTTON");
WebElement backToDesktop= wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return login.getDriver().findElement(By.className("modal-button-text"));
}
});
backToDesktop.click();
System.out.println("FOUND BACKTODESKTOP BUTTON");
FluentWait is a custom wait. You shouldn't need it in most cases. You should always start with a WebDriverWait and ExpectedConditions and if that doesn't work, then maybe investigate a FluentWait. My guess is that something simple like the below will work for you. This is just one example. You should look at all the different conditions you can wait for that are provided by ExpectedConditions. Probably the most common ones are waiting for an element to be visible or clickable.
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("someId")));
Selenium is displaying number of links on a page as 0 although there are many links on the page.
This is my code in java
dr.get("https://www.ebay.com");
List<WebElement> linksize = dr.findElements(By.tagName("a"));
System.out.println(linksize.size());
Output :
0
Wait until page loads for links
Modify your code to
dr.get("https://www.ebay.com");
waitForLoad(dr); // Here you are calling the below method
List<WebElement> linksize = dr.findElements(By.tagName("a"));
System.out.println(linksize.size());
You can use the below method as your util and can call anytime
void waitForLoad(WebDriver driver) {
ExpectedCondition<Boolean> pageLoadCondition = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(pageLoadCondition);
}
#Subhrapratim Bhattacharjee, it seems that you need to wait for the page to load. Try following code
WebDriver driver = new FirefoxDriver();
driver.get("https://www.ebay.com");
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
WebDriverWait wait = new WebDriverWait(driver, 30);
List<WebElement> linksize = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.tagName("a")));//driver.findElements(By.tagName("a"));
System.out.println(linksize.size());
I am using Java and Selenium to write a test. I have a drop down menu from which I need to select something. This is my code:
Select s= new Select(driver.findElement(By.xpath("blabla")));
s.selectByVisibleText("theName");
it works on Chrome but on Firefox 47 I get this error:
org.openqa.selenium.ElementNotVisibleException:
Element is not currently visible and so may not be interacted with
I know how to handle selecting from drop down menu by other ways, but I need to use Select object.
Use fluent wait to wait element, chrome is faster:
public static void waitUntilElementIsVisible(WebElement element, WebDriver driver)
{
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
wait.withTimeout(2, TimeUnit.MINUTES);
wait.ignoring(ElementNotVisibleException.class); //make sure that this exception is ignored
Function<WebDriver, WebElement> function = new Function<WebDriver, WebElement>()
{
public WebElement apply(WebDriver driver) {
System.out.println("Checking for the element!!");
if(element.isDisplayed() != true)
{
System.out.println("Target element is not visible");
}
return element;
}
};
wait.until(function);
}
Then you can call it:
WebElement el = driver.findElement(By.xpath("blabla"));
waitUntilElementIsVisible(el, driver);
You can use the WebDriverWait class to wait for the visibility of the element like this:
WebDriverWait wait = new WebDriverWait(driver, customTime);
WebDriver driver = new FirefoxDriver();
Select s = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("blabla")));
s.selectByVisibleText("theName");
I have an link in HTML and I use Page Object pattern to write scripts with Selenium Webdriver. But my link is hidden and I can't perform MouseMove action when object is initialized with pageFactory.
Here is my class:
public class DashboardPage {
WebDriver driver;
#FindBy(xpath = Constants.admin)
public WebElement adminButton;
#FindBy(xpath = Constants.usersAndRoles)
public WebElement usersAndRolesButton;
#FindBy(xpath = Constants.users)
public WebElement usersButton;
public DashboardPage (WebDriver dr){
driver =dr;
}
public UsersPage goToUsersPage(){
adminButton.click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Actions builder = new Actions(driver);
builder.moveToElement(usersAndRolesButton).build().perform();
//usersAndRolesButton.click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
usersButton.click();
return PageFactory.initElements(driver, UsersPage.class);
}
Try using scroll to element and perform operation on it. Try following function.Pass your element to function,page will scrolled to that element and then perform any other operation-
public void scrollToElement(WebElement element){
int elementPosition = element.getLocation().getY();
elementPosition = elementPosition-200; // You can change 200 to any value if your page have sticky header
System.out.println(elementPosition);
String js = String.format("window.scroll(0, %s)", elementPosition);
((JavascriptExecutor)driver).executeScript(js);
}
//other operation
element.click(); //etc....
The following code worked for me.
#FindBy(xpath = Constants.usersLink)
public WebElement usersLink;
public UsersPage goToUsersPage() {
JavascriptExecutor usersPage = (JavascriptExecutor) driver;
usersPage.executeScript("arguments[0].click();", usersLink);
return PageFactory.initElements(driver, UsersPage.class);
}