How to handle multiple alert popup confirmation in selenium.
E.g: If accepting popup window, it's asking again and again for the same window. and if that popup closed after clicking 5th time confirmation/dismiss how can we handle the same.
So please help me on this...
If you know the exact number of times this alert will pop up, you can use a simple loop with a hard coded number of retries. For example:
int retries = 5;
while (retries > 0) {
alertTriggerButton.click();
Alert alert = driver.switchTo().alert();
alert.accept();
retries--;
}
You should amend this code to make sure it works according to your page behavior so thinks like response times are taken into account (in other words - add relevant wait times if required).
You can use while. You're checking if the alert is present, and each time it is there, you resolve it according to that boolean value that you give it. When there is no new alert anymore, it will break and continue on.
public static void resolveAllAlerts(WebDriver driver, int timeout, boolean accept) {
while (isAlertPresent(driver, timeout)) {
resolveAlert(driver, accept);
}
}
private static boolean isAlertPresent(WebDriver driver, int timeout) {
try {
Alert a = new WebDriverWait(driver, timeout).until(ExpectedConditions.alertIsPresent());
if (a != null) {
return true;
} else {
throw new TimeoutException();
}
} catch (TimeoutException e) {
// log the exception;
return false;
}
}
private static void resolveAlert(WebDriver driver, boolean accept) {
if (accept) {
driver.switchTo().alert().accept();
} else {
driver.switchTo().alert().dismiss();
}
}
Related
Hi i am working on a selenium project and the top difficulty that i am having was waiting for XHR request to be completed. What i am currently doing is i wait for a request to be made using following expected condition,
public ExpectedCondition<Boolean> jQueryExpect (int expectedActive) {
ExpectedCondition<Boolean> jQLoad = new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver dr) {
try {
logger.log(Level.INFO,"Checking number of jQueries Active");
Long active = (Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active");
logger.log(Level.INFO,"jQuery''s active: {0}",active);
return (active >= expectedActive);
}
catch (Exception e) {
logger.log(Level.WARNING,"Error executing script in jQueryLoad method");
// no jQuery present
return true;
}
}
};
return jQLoad;
}
And then i wait for the jQuery to load using this expected condition
public ExpectedCondition<Boolean> jQueryLoad (int expectedActive) {
ExpectedCondition<Boolean> jQLoad = new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver dr) {
try {
logger.log(Level.INFO,"Checking number of jQueries Active");
Long active = (Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active");
logger.log(Level.INFO,"jQuery''s active: {0}",active);
return (active <= expectedActive);
}
catch (Exception e) {
logger.log(Level.WARNING,"Error executing script in jQueryLoad method");
// no jQuery present
return true;
}
}
};
return jQLoad;
}
This method is working pretty solid for now since i know how many requests to expect. But as you have already noticed it can easily break in future as number of requests made are changed for some reason.
I been looking at cypress documentation and found this. According to cypress documentation this waits for the specified requests to be made.
cy.wait(['#getUsers', '#getActivities', '#getComments']).then((xhrs) => {
// xhrs will now be an array of matching XHR's
// xhrs[0] <-- getUsers
// xhrs[1] <-- getActivities
// xhrs[2] <-- getComments
})
Is there any such method available in Selenium? or Is there any way this can be implemented? So far from what i have googled i got nothing. So any help will be appreciated.
You can locate Element and wait for element
There are Implicit and Explicit waits in selenium.
You can use either
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
or
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
More information: on this answer
When i try to run my scripts and call this method, when i enter URL into address bar, loading starts and loading take much time,
but sometime when refresh page page proper loaded on the spot so please help me out.
How can i handle this issue in automation.
public static MainPage LaunchBrowserAndLogin(String currentScriptName, String LoginUser) throws Throwable {
try {
killprocess();
LaunchBrowser();
String siteUrl = null;
if (excelSiteURL != null) {
if (excelSiteURL.equalsIgnoreCase("")) {
siteUrl = CONFIG.getProperty("siteName");
}else{
if (excelSiteURL.contains("SiteName")) {
siteUrl=excelSiteURL;
}
}
} else {
siteUrl = CONFIG.getProperty("SiteName");
}
driver.get("https://QA.YYYY.com/ABC9/#/login");
System.out.println("URL for Login: "+siteUrl);
CheckErrorPageNotFound();
driver.manage().timeouts().pageLoadTimeout(Long.parseLong(CONFIG.getProperty("pageLoadTime")), TimeUnit.SECONDS);
enterUserID(currentScriptName, LoginUser);
enterPasswd(currentScriptName);
MandatoryFieldSkipErrMsg("~~~~~~ Mandatory Field is skipped, Getting Error: ");
ClickLoginButton();
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
}catch(){
DesireScreenshot("AfterClickOnLoginButton");
String stackTrace = Throwables.getStackTraceAsString(t);
String errorMsg = t.getMessage();
errorMsg = "\n\n\n\n Login failed.See screenshot 'LoginFailed' \n\n\n\n" + errorMsg + stackTrace;
Exception c = new Exception(errorMsg);
ErrorUtil.addVerificationFailure(c);
killprocess();
IsBrowserPresentAlready = false;
throw new Exception(errorMsg);
}
return new MainPage(driver);
}
First you need to check whether page is fully loaded or not in that case we will use the below code.
new WebDriverWait(driver, 5).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
Then as per your question I believe that some web elements are not properly getting loaded. So what you can do add one more explicit wait and put that wait inside try catch block as shown below.
try
{
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(By.id("Abhishek")));
System.out.println("Completed");
}
catch( TimeoutException e)
{
System.out.println("Reloading");
driver.navigate().refresh();
}
If it is unable to find that element then in the catch block it will refresh the page and in this way you can proceed further.
Note: I could have written the script for you but application url is invalid.
I posed with a difficult task. I am fairly new to selenium and still working through the functionalities of waiting for elements and alike.
I have to manipulate some data on a website and then proceed to another. Problem: the manipulation invokes a script that makes a little "Saving..." label appear while the manipulated data is being processed in the background. I have to wait until I can proceed to the next website.
So here it is:
How do i wait for and element to DISAPPEAR? Thing is: It is always present in the DOM but only made visible by some script (I suppose, see image below).
This is what I tried but it just doesn't work - there is no waiting, selenium just proceeds to the next step (and gets stuck with an alert asking me if I want to leave or stay on the page because of the "saving...").
private By savingLableLocator = By.id("lblOrderHeaderSaving");
public boolean waitForSavingDone(By webelementLocator, Integer seconds){
WebDriverWait wait = new WebDriverWait(driver, seconds);
Boolean element = wait.until(ExpectedConditions.invisibilityOfElementLocated(webelementLocator));
return element;
}
UPDATE / SOLUTION:
I came up ith the following solution: I built my own method. Basically it checks in a loop for the CssValue to change.
the loops checks for a certain amount of time for the CSSVALUE "display" to go from "block" to another state.
public void waitForSavingOrderHeaderDone(Integer _seconds){
WebElement savingLbl = driver.findElement(By.id("lblOrderHeaderSaving"));
for (int second = 0;; second++) {
if (second >= _seconds)
System.out.println("Waiting for changes to be saved...");
try {
if (!("block".equals(savingLbl.getCssValue("display"))))
break;
} catch (Exception e) {
}
}
You can wait for a WebElement to throw a StaleElementReferenceException like this:
public void waitForInvisibility(WebElement webElement, int maxSeconds) {
Long startTime = System.currentTimeMillis();
try {
while (System.currentTimeMillis() - startTime < maxSeconds * 1000 && webElement.isDisplayed()) {}
} catch (StaleElementReferenceException e) {
return;
}
}
So you would pass in the WebElement you want to wait for, and the max amount of seconds you want to wait.
Webdriver has built in waiting functionality you just need to build in the condition to wait for.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return (driver.findElements(By.id("lblOrderHeaderSaving")).size() == 0);
}
});
I'm not sure, but you can try something like this :)
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //time in second
WebElement we = driver.findElement(By.id("lblOrderHeaderSaving"));
assertEquals("none", we.getCssValue("display"));
This works with selenium 2.4.0. you have to use the invisibility mehtod to find it.
final public static boolean waitForElToBeRemove(WebDriver driver, final By by) {
try {
driver.manage().timeouts()
.implicitlyWait(0, TimeUnit.SECONDS);
WebDriverWait wait = new WebDriverWait(UITestBase.driver,
DEFAULT_TIMEOUT);
boolean present = wait
.ignoring(StaleElementReferenceException.class)
.ignoring(NoSuchElementException.class)
.until(ExpectedConditions.invisibilityOfElementLocated(by));
return present;
} catch (Exception e) {
return false;
} finally {
driver.manage().timeouts()
.implicitlyWait(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
}
}
I used following C# code to handle this, you may convert it to Java
public bool WaitForElementDisapper(By element)
{
try
{
while (true)
{
try
{
if (driver.FindElement(element).Displayed)
Thread.Sleep(2000);
}
catch (NoSuchElementException)
{
break;
}
}
return true;
}
catch (Exception e)
{
logger.Error(e.Message);
return false;
}
}
You can also try waiting for the ajax calls to complete. I've used this to check when the page load is complete and all the elements are visible.
Here's the code - https://stackoverflow.com/a/46640938/4418897
You could use XPath and WebDriverWait to check whether display: none is present in the style attribute of an element. Here is an example:
// Specify the time in seconds the driver should wait while searching for an element which is not present yet.
int WAITING_TIME = 10;
// Use the driver for the browser you want to use.
ChromeDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, WAITING_TIME);
// Replace ELEMENT_ID with the ID of the element which should disappear.
// Waits unit style="display: none;" is present in the element, which means the element is not visible anymore.
driver.wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[#id='ELEMENT_ID'][contains(#style, 'display: block')]")));
Try using invisibilityOfElementLocated method.
You can reference example here How to wait until an element no longer exists in Selenium?
enter image description hereI created my own method for element disappearing from dom....
In Conditions class (In .m2\repository\org\seleniumhq\selenium\selenium-support\3.141.59\selenium-support-3.141.59.jar!\org\openqa\selenium\support\ui\ExpectedConditions.class)
we can see that 'isInvisible' method with 'isDisplayed' method,,, i wrote the same with 'isEnabled'
public static ExpectedCondition<Boolean> invisibilityOf(final WebElement element) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver webDriver) {
return isRemovedFromDom(element);
}
#Override
public String toString() {
return "invisibility of " + element;
}
};
}
private static boolean isRemovedFromDom(final WebElement element) {
try {
return !element.isEnabled();
} catch (StaleElementReferenceException ignored) {
return true;
}
}
I've written a standalone function for my selenium script so that when I want to interact with an object I first check if it exists, to do this I've already specified things such the method to identify it by and the data to use etc, and have some methods like so: -
public WebElement waitforElement(individualThreadSession threadSesh) {
String IDString = threadSesh.objLocVal; //This will be the string value to use to identify
String IDType = threadSesh.objLocType; //This will be something like "CSS"/"XPATH" etc
WebElement returnedElement = null;
for (int second = 0; second < threadSesh.sessionWait; second++) {
Action tempAction = new Action();
tempAction.simpleWait(1);
try {
if(IDType.toString().equals("CSS")){
if(isElementPresent(By.cssSelector(IDString), threadSesh)){
returnedElement = threadSesh.driver.findElement(By.cssSelector(IDString));
break;
}
}
else if(IDType.toString().equals("XPATH")){
if(isElementPresent(By.xpath(IDString), threadSesh)) {
returnedElement = threadSesh.driver.findElement(By.xpath(IDString));
break;
}
}
else if(IDType.toString().equals("ID")){
if(isElementPresent(By.id(IDString), threadSesh)) {
returnedElement = threadSesh.driver.findElement(By.id(IDString));
break;
}
}
else if(IDType.toString().equals("NAME")){
if(isElementPresent(By.name(IDString), threadSesh)){
returnedElement = threadSesh.driver.findElement(By.name(IDString));
break;
}
}
else if(IDType.toString().equals("PARTIALLINKTEXT")){
if(isElementPresent(By.partialLinkText(IDString), threadSesh)) {
returnedElement = threadSesh.driver.findElement(By.partialLinkText(IDString));
break;
}
}
else if(IDType.toString().equals("LINKTEXT")){
if(isElementPresent(By.linkText(IDString), threadSesh)) {
returnedElement = threadSesh.driver.findElement(By.linkText(IDString));
break;
}
}
} catch (Exception e) {System.out.println("When trying to find the obj error encountered - " + e);}
}
return (returnedElement);
}
and this: -
public boolean isElementPresent(By myObject, individualThreadSession threadSesh) {
try{
System.out.println("actually check!");
if (threadSesh.driver.findElement(myObject).isEnabled() && threadSesh.driver.findElement(myObject).isDisplayed()) {
return true;
} else {
return false;
}
} catch (NoSuchElementException e){
return(false);
}
}
But every time I run this it errors with the below and exits the test: -
Test failed with the following error: - org.openqa.selenium.NoSuchElementException:
Unable to find element with xpath == .//*[#id='main']/div[1]/div[1]/h1/span
Shouldn't this work?
I think it could be because I also have an WebDriverEventListener running which I'm guessing is catching this error and exiting the test etc, is there any way I can stop this eventlistener from listening during this waitforelement process?
If not is there a way I can check if the object is enable and visible or not without it throwing an exception?
The event listener is like so: -
WebDriverEventListener listener = new AbstractWebDriverEventListener() {
#Override
public void onException(Throwable t, WebDriver driver) {
//Add in take screenshot here at some stage!
if(!errorsCaught){
errorsCaught=true;
try{
driver.quit();
}catch(WebDriverException theError){}
System.out.println();
System.out.println(Thread.currentThread().getName() + " has encountered an error ");
individualThreadSession.this.endSession(individualThreadSession.this, t);
}
}
};
More digging reveals that it looks like it is the listener picking up things before the catch does anything with it, so now I need to somehow work out how to get it to ignore the error! Any ideas?
I had failed to spot one key line in my event listener, the #Override! This was causing my listener to pick up all exceptions before any catch's I may have also put in, and my listener will just kill off the session and close the run as it should (even though I don't want it to do something in that case).
To get round this issue as I always go through the same route above to check for an object before interacting with it I can be fairly confident that this object will always be there before trying anything or timeout and exit gracefully.
So I've inserted a basic check like so: -
t.getClass().getSimpleName().toLowerCase().equals("nosuchelementexception")
So if the error is a nosuchelementexception I don't bother doing anything with it and just go back into my loop, simples! :)
If findEelement is unable to find the element you will get a NoSuchElementException. This is expected. Instead, try to use findElements that will return an empty list instead of an exception if no elements are present.
Two ways of solving your problem:
Boolean isPresent = driver.findElements(myObject).size()<0
or
private boolean doesElementExist (myObject) {
try {
driver.findElement(myObject);
} catch (NoSuchElementException e) {
return false;
}
return true;}
I have web-driver test which is stuck because a pop-up window appears. How ca I close it in test?
Here is my code:
#Test
public void canGoToSomePage() throws Exception {
final WebDriver webDriver = getFireFoxDriver();
webDriver.get(getRouteAbsolute("Application.index"));
WebElement someElement = webDriver.findElement(By.id("some_id_here"));
someElement.click();
// HERE I GOT AUTHENTICATION POP-UP I WANT TO CLOSE
assertNotNull(webDriver.findElement(By.id("some_2_id")));
}
Try this,
Alert alert = driver.switchTo().alert();
alert.accept();
I have never used alert before, I used to silent the pop up using JS before. You could do that too, but i guess Alert would be the first choice.
EDIT#1
Here is how to use Java script to silent the pop up. Note that it has to be executed BEFORE the click that causes the popup to show up. Based on whether your pop up is alert, confirm or prompt, you will have to use something like below.
((JavascriptExecutor)driver).executeScript("window.alert = function(msg) { return true; }");
((JavascriptExecutor)driver).executeScript("window.confirm = function(msg) { return true; }");
((JavascriptExecutor)driver).executeScript("window.prompt = function(msg) { return true; }");