Security warning observed on Firefox:
The information you have entered on this page will be sent over an insecure connection and could be read by a third party.
Are you sure you want to send this information?
Click Continue or cancel
To click on continue I have tried using Robot class method
Robot robot =new Robot();
robot.keyPress(KeyEvent.VK_LEFT);
robot.keyPress(KeyEvent.VK_ENTER);
System.out.println("key pressed");
robot.keyRelease(KeyEvent.VK_ENTER);
But I get UnhandledAlertException: Unexpected modal dialog (text: The information you have entered on this page will be sent over an insecure connection and could be read by a third party.
Are you sure you want to send this information?): The information you have entered on this page will be sent over an insecure connection and could be read by a third party.
Are you sure you want to send this information?
I also tried manually clicking on continue , then continue with selenium script
1 Manually close
2 WebElement success = wait.until(ExpectedConditions
.visibilityOfElementLocated(By.cssSelector(".error-msg")));
Then i get WebDriver exception that ".error-msg" is not a Web Element
Following worked for me in Java
private void acceptSecurityAlert() {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS)
.pollingEvery(3, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
Alert alert = wait.until(new Function<WebDriver, Alert>() {
public Alert apply(WebDriver driver) {
try {
return driver.switchTo().alert();
} catch(NoAlertPresentException e) {
return null;
}
}
});
alert.accept();
}
Related
I am trying to check if web page is loaded completed or not (i.e. checking that all the control is loaded) in selenium.
I tried below code:
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
but even if page is loading above code does not wait.
I know that I can check for particular element to check if its visible/clickable etc but I am looking for some generic solution
As you mentioned if there is any generic function to check if the page has completely loaded through Selenium the answer is No.
First let us have a look at your code trial which is as follows :
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
The parameter pageLoadTimeout in the above line of code doesn't really reseambles to actual pageLoadTimeout().
Here you can find a detailed discussion of pageLoadTimeout in Selenium not working
Now as your usecase relates to page being completely loaded you can use the pageLoadStrategy() set to normal [ the supported values being none, eager or normal ] using either through an instance of DesiredCapabilities Class or ChromeOptions Class as follows :
Using DesiredCapabilities Class :
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
public class myDemo
{
public static void main(String[] args) throws Exception
{
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
DesiredCapabilities dcap = new DesiredCapabilities();
dcap.setCapability("pageLoadStrategy", "normal");
FirefoxOptions opt = new FirefoxOptions();
opt.merge(dcap);
WebDriver driver = new FirefoxDriver(opt);
driver.get("https://www.google.com/");
System.out.println(driver.getTitle());
driver.quit();
}
}
Using ChromeOptions Class :
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.PageLoadStrategy;
public class myDemo
{
public static void main(String[] args) throws Exception
{
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
FirefoxOptions opt = new FirefoxOptions();
opt.setPageLoadStrategy(PageLoadStrategy.NORMAL);
WebDriver driver = new FirefoxDriver(opt);
driver.get("https://www.google.com/");
System.out.println(driver.getTitle());
driver.quit();
}
}
You can find a detailed discussion in Page load strategy for Chrome driver (Updated till Selenium v3.12.0)
Now setting PageLoadStrategy to NORMAL and your code trial both ensures that the Browser Client have (i.e. the Web Browser) have attained 'document.readyState' equal to "complete". Once this condition is fulfilled Selenium performs the next line of code.
You can find a detailed discussion in Selenium IE WebDriver only works while debugging
But the Browser Client attaining 'document.readyState' equal to "complete" still doesn't guarantees that all the JavaScript and Ajax Calls have completed.
To wait for the all the JavaScript and Ajax Calls to complete you can write a function as follows :
public void WaitForAjax2Complete() throws InterruptedException
{
while (true)
{
if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){
break;
}
Thread.sleep(100);
}
}
You can find a detailed discussion in Wait for ajax request to complete - selenium webdriver
Now, the above two approaches through PageLoadStrategy and "return jQuery.active == 0" looks to be waiting for indefinite events. So for a definite wait you can induce WebDriverWait inconjunction with ExpectedConditions set to titleContains() method which will ensure that the Page Title (i.e. the Web Page) is visible and assume the all the elements are also visible as follows :
driver.get("https://www.google.com/");
new WebDriverWait(driver, 10).until(ExpectedConditions.titleContains("partial_title_of_application_under_test"));
System.out.println(driver.getTitle());
driver.quit();
Now, at times it is possible though the Page Title will match your Application Title still the desired element you want to interact haven't completed loading. So a more granular approach would be to induce WebDriverWait inconjunction with ExpectedConditions set to visibilityOfElementLocated() method which will make your program wait for the desired element to be visible as follows :
driver.get("https://www.google.com/");
WebElement ele = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath_of_the_desired_element")));
System.out.println(ele.getText());
driver.quit();
References
You can find a couple of relevant detailed discussions in:
Selenium IE WebDriver only works while debugging
Selenium how to manage wait for page load?
I use selenium too and I had the same problem, to fix that I just wait also for the jQuery to load.
So if you have the same issue try this also
((Long) ((JavascriptExecutor) browser).executeScript("return jQuery.active") == 0);
You can wrap both function in a method and check until both page and jQuery is loaded
Implement this, Its working for many of us including me. It includes Web Page wait on JavaScript, Angular, JQuery if its there.
If your Application is containing Javascript & JQuery you can write code for only those,
By define it in single method and you can Call it anywhere:
// Wait for jQuery to load
{
ExpectedCondition<Boolean> jQueryLoad = driver -> ((Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active") == 0);
boolean jqueryReady = (Boolean) js.executeScript("return jQuery.active==0");
if (!jqueryReady) {
// System.out.println("JQuery is NOT Ready!");
wait.until(jQueryLoad);
}
wait.until(jQueryLoad);
}
// Wait for ANGULAR to load
{
String angularReadyScript = "return angular.element(document).injector().get('$http').pendingRequests.length === 0";
ExpectedCondition<Boolean> angularLoad = driver -> Boolean.valueOf(((JavascriptExecutor) driver).executeScript(angularReadyScript).toString());
boolean angularReady = Boolean.valueOf(js.executeScript(angularReadyScript).toString());
if (!angularReady) {
// System.out.println("ANGULAR is NOT Ready!");
wait.until(angularLoad);
}
}
// Wait for Javascript to load
{
ExpectedCondition<Boolean> jsLoad = driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").toString()
.equals("complete");
boolean jsReady = (Boolean) js.executeScript("return document.readyState").toString().equals("complete");
// Wait Javascript until it is Ready!
if (!jsReady) {
// System.out.println("JS in NOT Ready!");
wait.until(jsLoad);
}
}
Click here for Reference Link
Let me know if you stuck anywhere by implementing.
It overcomes the use of Thread or Explicit Wait.
public static void waitForPageToLoad(long timeOutInSeconds) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
};
try {
System.out.println("Waiting for page to load...");
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeOutInSeconds);
wait.until(expectation);
} catch (Throwable error) {
System.out.println(
"Timeout waiting for Page Load Request to complete after " + timeOutInSeconds + " seconds");
}
}
Try this method
This works for me well with dynamically rendered websites:
Wait for complete page to load
WebDriverWait wait = new WebDriverWait(driver, 50);
wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
Make another implicit wait with a dummy condition which would always fail
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'" + "This text will always fail :)" + "')]"))); // condition you are certain won't be true
}
catch (TimeoutException te) {
}
Finally, instead of getting the html source - which would in most of one page applications would give you a different result , pull the outerhtml of the first html tag
String script = "return document.getElementsByTagName(\"html\")[0].outerHTML;";
content = ((JavascriptExecutor) driver).executeScript(script).toString();
There is a easy way to do it. When you first request the state via javascript, it tells you that the page is complete, but after that it enters the state loading. The first complete state was the initial page!
So my proposal is to check for a complete state after a loading state. Check this code in PHP, easily translatable to another language.
$prevStatus = '';
$checkStatus = function ($driver) use (&$prevStatus){
$status = $driver->executeScript("return document.readyState");
if ($prevStatus=='' && $status=='loading'){
//save the previous status and continue waiting
$prevStatus = $status;
return false;
}
if ($prevStatus=='loading' && $status=='complete'){
//loading -> complete, stop waiting, it is finish!
return true;
}
//continue waiting
return false;
};
$this->driver->wait(20, 150)->until($checkStatus);
Checking for a element to be present also works well, but you need to make sure that this element is only present in the destination page.
Something like this should work (please excuse the python in a java answer):
idle = driver.execute_async_script("""
window.requestIdleCallback(() => {
arguments[0](true)
})
""")
This should block until the event loop is idle which means all assets should be loaded.
How to press the OK button as per the image.
I can switch to this window. but it is not loaded till i click ok, so there is no any elements.
Alert handle does't helped too.
Autoit cannot detect this pop up message too.
disable-notifications cant help too.
Any ideas?
Two screeshots is added.
Firefox snapshot:
Chrome Snapshot:
p.companieGenreal.sActivities().click();
driver.switchTo().defaultContent();
String parent = driver.getWindowHandle();
p.companieGenreal.sAddNew().click();
p.companieGenreal.sAddJobOrder().click();
p.companieGenreal.sContract().click();
swithToChildWindow(parent);
driver.switchTo().alert().accept();
To treat it as an alert try this:
Alert a = driver.switchTo().alert();
a.confirm();
If it can be closed with Escape key, send Escape keypress like this (or ENTER if it closes when Enter is hit):
Actions action = new Actions(driver);
action.sendKeys(Keys.ESCAPE);
beforeunload
The beforeunload event is fired when the window, the document and its resources are about to be unloaded. At this point of time the document is still visible and the event is still cancelable.
Note: Since 25 May 2011, the HTML5 specification states that calls to window.alert(), window.confirm(), and window.prompt() methods may be ignored during this event.
Solution
There are multiple ways to disable this popup as follows:
Firefox: If you are using Firefox as your Browser Client you can use an instance of FirefoxOptions() and set the preference dom.disable_beforeunload to true as follows:
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
FirefoxOptions firefox_option = new FirefoxOptions();
firefox_option.addPreference("dom.disable_beforeunload", true);
WebDriver firefox_driver = new FirefoxDriver(firefox_option);
firefox_driver.get("https://stackoverflow.com/");
Chrome: If you are using Chrome as your Browser Client you can use an instance of ChromeOptions() and add the argument --disable-popup-blocking as follows:
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions chrome_option = new ChromeOptions();
chrome_option.addArguments("--disable-popup-blocking");
chrome_option.addArguments("start-maximized");
chrome_option.addArguments("disable-infobars");
WebDriver chrome_driver = new ChromeDriver(chrome_option);
chrome_driver.get("https://stackoverflow.com/");
try using this :
public static void acceptAlertUsingJs(WebDriver driver) {
((JavascriptExecutor)driver).executeScript("window.alert = function(msg){return true;};");
((JavascriptExecutor)driver).executeScript("window.prompt = function(msg) { return true; }");
((JavascriptExecutor)driver).executeScript("window.confirm = function(msg) { return true; }");
}
Please try the below code and see if it helps:
if (isAlertPresent()){
driver.switchTo().alert().accept();
driver.switchTo().defaultContent();
}
}
public static boolean isAlertPresent() {
try {
driver.switchTo().alert();
Thread.sleep(5000);
return true;
}// try
catch (Exception e) {
return false;
}// catch
}
I have the same kind of issue a modal pop up window opens to which i am able to switch to and click the OK button but cannot fetch the text present in it. The modal dialog is shared in the screenshot and has no html tags hence i cannot locate the text in it using any locator. I tried using driver.switchTo().alert().getText() to fetch the text present in it.
If that is an alert you could handle using below methods:
driver.switchTo().alert().accept();
"Actions class":
Actions builder=new Actions(driver);
builder.sendKeys(keys.ESCAPE);
if the above two methods didn't work then there is a special alert type called "sweet alert" which can be inspected and write code for that.
I am using java selenium for saving web data if any changes made.
Web page contains two buttons 'Confirm' and 'Cancel'. If i made any changes in web page, both 'confirm' and 'cancel' buttons will be visible at the time i can click confirm button by using below code .
WebElement confirm =wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Confirm')]")));
confirm.click();
If there is no changes in web page , Confirm button will get disabled(grayed) at the time i want to click Cancel button Automatically.
I have tried with below code , it is not working. Please help on this.
try
{
WebElement confirm = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Confirm')]")));
confirm.click();
}
catch (ElementNotVisibleException exception)
{
WebElement cancel = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Cancel')]")));
cancel.click();
}
Why do you want to complicate things? Keep it simple.
WebElement confirm = driver.findElement(By.id("<your confirm button id>"));
WebElement cancel= driver.findElement(By.id("<your cancel id>"));
if(confirm.isEnabled())
{
confirm.click();
}
else
{
cancel.click();
}
You may also try with confirm.isDisplayed();
You can try catching the exception when click on 'Confirm' button fails and as part of exception handling you can click on 'Cancel' button in following way:
try {
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Confirm')]")));
driver.findElement(By.xpath("//button[contains(text(), 'Confirm')]")).click();
} catch (Exception we) {
System.out.println("'Confirm' button is not clickable, hence trying to click on 'Cancel' button");
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Cancel')]")));
driver.findElement(By.xpath("//button[contains(text(), 'Cancel')]")).click();
}
UPDATE 1:
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//button[contains(text(), 'Confirm')]")));
WebElement confirmButton = driver.findElement(By.xpath("//button[contains(text(), 'Confirm')]"));
if (confirmButton.isEnabled())
confirmButton.click();
else
driver.findElement(By.xpath("//button[contains(text(), 'Cancel')]")).click();
Let me know, whether it works for you.
I am trying to automate Goibibo Website in Selenium using Java. After Clicking on Sign in Tab, login pop up is displaying. How to switch to pop up so that I can enter details into the Goibibo Pop up. I wrote the following code:
public class Testclass1 {
public static void main(String[] args) throws InterruptedException{
System.setProperty("webdriver.chrome.driver", "D://chromedriver_win32//chromedriver.exe");
WebDriver Driver = new ChromeDriver();
Driver.manage().window().maximize();
Driver.get("https://www.goibibo.com/");
Thread.sleep(5000);
//HANDLE THE POP UP
String handle = Driver.getWindowHandle();
System.out.println(handle);
// Click on the Button "New Message Window"
Driver.findElement(By.linkText("Sign In")).click();
Thread.sleep(3000);
// Store and Print the name of all the windows open
Set handles = Driver.getWindowHandles();
System.out.println(handles);
// Pass a window handle to the other window
for (String handle1 : Driver.getWindowHandles()) {
System.out.println(handle1);
Driver.switchTo().window(handle1);
}
Thread.sleep(3000);
Driver.findElement(By.name("username")).sendKeys("bittu.agrawal773#gmail.com");
//WAIT
}
}
Opened popup is not a new window popup, it's just simple HTML login popup present is iframe which can be simply handled by switching to iframe as below working code :-
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
driver.get("https://www.goibibo.com/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Sign In"))).click();
//switch to popup iframe to enter login credentials into form
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("authiframe"));
//now enter login credentials
driver.findElement(By.id("id_username")).sendKeys("username");
driver.findElement(By.id("id_password")).sendKeys("password");
//now click on sign in button
driver.findElement(By.id("signinBtn")).click();
Note:- For better way, you should use WebDriverWait to wait explicitly for element with certain ExpectedConditions instead of Thread.sleep().
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; }");