How can I create click method which can be click in the button until the attribute shows? Something like loop until but with timer (if it's not found attribute after 10 seconds, display an error). I have created something like that, but code give me NullPointerException when not found attribute:
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement button = driver.findElement(By.xpath("xpath"));
String attribute = button.getAttribute("disabled");
button.click();
if(attribute .equals("true"))
return true;
else
return false;
}
});
I got similar problem and my solution was to write a function that tries to click on the object and when it is not present it waits a second and tries once again. After 10 times of trying it returns null.
It works beautifully for me. Goes like this:
WebElement tryfind(WebDriver browser, By id)
{
WebElement ttwel=null;
for (int i=0;i<10;i++)
{
try
{
ttwel=browser.findElement(id);
break;
}
catch (NoSuchElementException ex)
{
sleep(1000);
}
}
return ttwel;
}
void sleep(int mills)
{
try
{
Thread.sleep(mills);
}
catch (InterruptedException ex)
{
}
}
You might add waiting for disabled attribute to this method, something like:
for (int i=0;i<10;i++)
{
try
{
ttwel=browser.findElement(id);
String attribute = button.getAttribute("disabled");
if (attribute==null) sleep(1000);
else break;
}
catch (NoSuchElementException ex)
{
sleep(1000);
}
}
Why don't you add a try catch block like this below to catch the NullPointerException and return false in that case
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement button = driver.findElement(By.xpath("xpath"));
try {
String attribute = button.getAttribute("disabled");
button.click();
if (attribute.equals("true")) {
return true;
}
} catch (NullPointerException e) {
return false;
}
return false;
}
});
Related
I do have a method that waits for the JavaScript to load in the browser. From Selenium 3 (3.141.59), I have shifted to Selenium 4 (4.0.0-alpha-7)
This return code/statement doesnt work with Selenium 4
return wait.until(jQueryLoad) && wait.until(jsLoad);
What would be the correct return statement for this? I have tried several options but nothing worked. Please see the code structure for the method/function below. Your thoughts, ideas and answers will be highly appreaciated.
public static boolean waitForJStoLoad() {
WebDriverWait wait = new WebDriverWait(getDriver(), Duration.ofSeconds(30));
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver arg0) {
try {
Long state = (Long) ((JavascriptExecutor) arg0).executeScript("return jQuery.active");
return (state == 0);
} catch (Exception e) {
return true;
}
}
};
// wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver arg0) {
String state = (String) ((JavascriptExecutor) arg0).executeScript("return document.readyState;");
return state.equalsIgnoreCase("complete");
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}
Well, I'm using standard Selenium 3 and not checking JavaScripts, but I do have several simple methods validating some conditions with the Expected Conditons and returning Boolean.
Something like this:
public boolean waitForElementToDisappear(By element){
try {
wait.until((ExpectedConditions.invisibilityOfElementLocated(element)));
return true;
}catch (Throwable t){
return false;
}
}
Everytime got StaleElementReferenceException exception.
Here is a method, pls help.
private void selectAndClickRow(String elementName, boolean doubleClick) {
try {
String elementXpath = "//tr//td//div[contains(text(),'" + elementName + "')]";
new WebDriverWait(Init.getWebDriver(), Init.getTimeOutInSeconds()).until(ExpectedConditions.visibilityOf(Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath(elementXpath))));
WebElement row = table.findElements(By.xpath(elementXpath)).get(0);
row.click();
if (doubleClick) {
row.click();
}
Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath("//tr//td[contains(#class,'selected')]//div[contains(text(),'" + elementName + "')]"));
} catch (StaleElementReferenceException e) {
freeze(1);
selectAndClickRow(elementName, doubleClick);
}
waitToLoad();
}
public WebElement waitUntilElementAppearsInDom(By by) {
Wait wait = new WebDriverWait(Init.getWebDriver(), (long)Init.getTimeOutInSeconds());
wait.until(ExpectedConditions.presenceOfElementLocated(by));
return Init.getWebDriver().findElement(by);
}
I already added an element research and waiting for a second. It doesn't help.
I guess, you are trying to double click on a element. You can use actions class as given below instead of clicking twice on a element.
private void selectAndClickRow(String elementName, boolean doubleClick) {
try {
String elementXpath = "//tr//td//div[contains(text(),'" + elementName + "')]";
new WebDriverWait(Init.getWebDriver(), Init.getTimeOutInSeconds()).until(ExpectedConditions.visibilityOf(Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath(elementXpath))));
WebElement row = table.findElements(By.xpath(elementXpath)).get(0);
new Actions(driver).doubleClick(row).perform();
} catch (StaleElementReferenceException e) {
//freeze(1);
//selectAndClickRow(elementName, doubleClick);
}
waitToLoad();
}
I am working on Selenium webDriver in which I am using the method driver.manage().deleteAllCookies();
But this method is deleting all cookies from the current domain except one. Strange!!
I am using Chrome right now.
Can anyone suggest what could be the possible cause and what we can do to delete all cookies for the current domain?
driver.manage().deleteAllCookies();
This will only delete cookies on current domain. It won't delete cookies of any other domain.
So if you need to delete cookies of those domain then you need to first browse to a page from that domain and then call the deleteAllCookies method again
I had to wait all ajax operations to finish then call deleteAllCookies(), then it worked.
public void ajaxWait(long seconds) {
try{
while(!waitForJSandJQueryToLoad()) {
try {
Thread.sleep(1000);
seconds -= 1;
if (seconds <= 0) {
return;
}
} catch (InterruptedException var4) {
var4.printStackTrace();
}
}
} catch(Exception e){
e.printStackTrace();
}
}
public boolean waitForJSandJQueryToLoad() {
WebDriverWait wait = new WebDriverWait(driver, 20);
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
try {
return ((Long)((JavascriptExecutor)driver).executeScript("return jQuery.active") == 0);
}
catch (Exception e) {
// no jQuery present
e.printStackTrace();
return true;
}
}
};
// wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState")
.toString().equals("complete");
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}
I had the same issue. I wanted to log out of the system. I thought that I had deleted all cookies by calling:
driver.manage().deleteAllCookies();
After the statement finished, however, the system navigated me to the home page.
The solution for me is to navigate to log in page then delete the cookies again:
driver.get(target_url);
driver.manage().deleteAllCookies();
I want to open the mail by clicking on it, after receiving the activation mail.
For that I am using keyword driven framework.
So can anyone please let me know that how can we click on element without using List<>.
Because in my coding structure I am returning the object of Webelement instead of List<> object.
Note: Please suggest the solution without using JavaMail Api or if suggest please let me know according to the keyword driven framework.
Way of code structure where I find the elements in one method and in another method after getting an element perform the operations:
private boolean operateWebDriver(String operation, String Locator,
String value, String objectName) throws Exception {
boolean testCaseStep = false;
try {
System.out.println("Operation execution in progress");
WebElement temp = getElement(Locator, objectName);
System.out.println("Get Element ::"+temp);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
//For performing click event on any of the button, radio button, drop-down etc.
if (operation.equalsIgnoreCase("Click")) {
temp.click();
}
/*Trying to click on subject line of "Email"*/
if (operation.equalsIgnoreCase("Click_anElement")) {
Thread.sleep(6000L);
Select select = new Select(temp);
List<WebElement> options= select.getOptions();
for(WebElement option:options){
System.out.println(option.getText());
}
/*try
{
if(temp.getText().equals(value)){
temp.click();
}
}
catch(Exception e){
System.out.println(e.getCause());
}*/
/*if (value != null) {
temp.click();
}*/
}
}
testCaseStep = true;
} catch (Exception e) {
System.out.println("Exception occurred operateWebDriver"
+ e.getMessage());
System.out.println("Taking Screen Shot");
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./Screenshots/"+screenshotName+".png"));
System.out.println("Screenshot taken");
}
return testCaseStep;
}
public WebElement getElement(String locator, String objectName) throws Exception {
WebElement temp = null;
System.out.println("Locator-->" + locator);
if (locator.equalsIgnoreCase("id")) {
temp = driver.findElement(By.id(objectName));
} else if (locator.equalsIgnoreCase("xpath")) {
temp = driver.findElement(By.xpath(objectName));
System.out.println("xpath temp ----->" + temp);
} else if (locator.equalsIgnoreCase("name")) {
temp = driver.findElement(By.name(objectName));
}else if (locator.equalsIgnoreCase("cssSelector")) {
temp = driver.findElement(By.cssSelector(objectName));
}
return temp;
}
I am writing tests for a web App using selenium webDriver and came across a scenario where when I try to delete a link the browser I get a popup saying:
Delete : "dummyname" Are you sure?
The browser page is asking you to confirm that you want to delete data, with 2 buttons: OK and cancel.
How do I click on those buttons?
For ok
driver.switchTo().alert().accept();
For cancel
driver.switchTo().alert().dismiss();
Hope it will help you :)
You should throw something like this in your BasePage.java and call acceptAlert() or dismissAlert(), but the magic lies in the code as Shubham Jain described above.
protected void acceptAlert() {
waitFor(new BooleanCondition() {
public Boolean apply(WebDriver webDriver) {
try {
webDriver.switchTo().alert().accept();
return true;
} catch (WebDriverException ex) {
return false;
}
}
public String describeFailure() {
return COULD_NOT_LOCATE_OR_ACCEPT_ALERT_BOX;
}
});
}
protected void dismissAlert() {
waitFor(new BooleanCondition() {
public Boolean apply(WebDriver webDriver) {
try {
webDriver.switchTo().alert().dismiss();
return true;
} catch (WebDriverException ex) {
return false;
}
}
public String describeFailure() {
return COULD_NOT_LOCATE_OR_ACCEPT_ALERT_BOX;
}
});
}