How can I tell Selenium to press cancel on a print popup? - java

I am checking whether or not a page appears using Selenium. When I click the page, however, a printer print prompt appears (like the window that says select printer and such). How can I have Selenium close this window by hitting cancel?
I tried looking to alerts, but it seems like those will not work since the print window is a system prompt. It does not recognize any alerts appearing.
The most recent I tried using is by just sending keys like tab and enter in order to have the cancel button selected, however, it doesn't recognize any keys as being pressed.
How can I handle this case?
public static boolean printButton() throws Exception {
WebDriver driver = new FirefoxDriver();
driver.get("website");
try {
Thread.sleep(3000);
WebElement temp = driver.findElement(By.xpath("//*[#id='block-print-ui-print-links']/div/span/a"));
temp.click();
Actions action = new Actions(driver);
action.sendKeys(Keys.TAB).sendKeys(Keys.ENTER);
Thread.sleep(6000);
}
catch (Exception e) {
System.out.println("No button.");
driver.close();
return false;
}

I would simply disable the print dialog by overriding the print method :
((JavascriptExecutor)driver).executeScript("window.print=function(){};");
But if you goal is to test that the printing is called then :
// get the print button
WebElement print_button = driver.findElement(By.cssSelector("..."));
// click on the print button and wait for print to be called
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);
((JavascriptExecutor)driver).executeAsyncScript(
"var callback = arguments[1];" +
"window.print = function(){callback();};" +
"arguments[0].click();"
, print_button);

If you are going for testing only Chrome browser here is mine solution. Because of 'Robot' class or disabling print didn't work for my case.
// Choosing the second window which is the print dialog.
// Switching to opened window of print dialog.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
// Runs javascript code for cancelling print operation.
// This code only executes for Chrome browsers.
JavascriptExecutor executor = (JavascriptExecutor) driver.getWebDriver();
executor.executeScript("document.getElementsByClassName('cancel')[0].click();");
// Switches to main window after print dialog operation.
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
Edit: In Chrome 71 this doesn't seem to work anymore since the script can't find the Cancel button. I could make it work by changing the line to:
executor.executeScript("document.querySelector(\"print-preview-app\").shadowRoot.querySelector(\"print-preview-header\").shadowRoot.querySelector(\"paper-button.cancel-button\").click();");

Actually you can't handle windows (OS) dialogs inside Selenium WebDriver.
This what the selenium team answers here
The current team position is that the print dialog is out of scope for
the project. WebDriver/Selenium is focused on emulating a user's
interaction with the rendered content of a web page. Other aspects of
the browser including, but not limited to print dialogs, save dialogs,
and browser chrome, are all out of scope.
You can try different approach like AutoIt

we can also use key for handling the print or press the cancel button operation. and it works for me.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
WebElement webElement = driver.findElement(By.tagName("body"));
webElement.sendKeys(Keys.TAB);
webElement.sendKeys(Keys.ENTER);
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());

Native window based dialog can be handled by AutoItX as described in the following code
File file = new File("lib", jacobDllVersionToUse);
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
WebDriver driver = new FirefoxDriver();
driver.get("http://www.joecolantonio.com/SeleniumTestPage.html");
WebElement printButton = driver.findElement(By.id("printButton"));
printButton.click();
AutoItX x = new AutoItX();
x.winActivate("Print");
x.winWaitActive("Print");
x.controlClick("Print", "", "1058");
x.ControlSetText("Print", "", "1153", "50");
Thread.sleep(3000); //This was added just so you could see that the values did change.
x.controlClick("Print", "", "2");
Reference : http://www.joecolantonio.com/2014/07/21/selenium-how-to-handle-windows-based-dialogs-and-pop-ups/

Sometimes 2 different statements as above (webElement.sendKeys(Keys.TAB)
webElement.sendKeys(Keys.ENTER)) will not work, you can use with combination of Tab and Enter keys as below, This will close the Print preview window.
Using C# :
Driver.SwitchTo().Window(Driver.WindowHandles[1]);
IWebElement element = Driver.FindElement(By.TagName("body"));
element.SendKeys(Keys.Tab + Keys.Enter);
Driver.SwitchTo().Window(Driver.WindowHandles[0]);

Erçin Akçay answer updated.
// Choosing the second window which is the print dialog.
// Switching to opened window of print dialog.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
// Runs javascript code for cancelling print operation.
// This code only executes for Chrome browsers.
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.querySelector(\"body > print-preview-app\").shadowRoot.querySelector(\"#sidebar\").shadowRoot.querySelector(\"print-preview-button-strip\").shadowRoot.querySelector(\"div > cr-button.cancel-button\").click();");
// Switches to main window after print dialog operation.
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());

Related

Selenium alert only shows in debug mode

I am testing a site page using Webdriver/Java which contains many fields. One of the fields is a dropdown box (or select box) and it contains validation upon losing focus (e.g. tabbing out). So if I select a particular option in the dropdown and tab to the next field, an alert box will pop up saying "You cannot choose that!".
Now I am doing code that checks for the presence of the alert box, and accepts it, however this is only working for me in DEBUG mode. When running the test (i.e. not in debug) I get "Timed out after 10 seconds waiting for alert to be present Build info: version: '2.53.0'".
I understand that this is probably a timing issue since it works in DEBUG mode, but I can't understand why as I'm using ExpectedConditions.alertIsPresent(). The code where this is failing is here:
WebElement currentElement = driver.findElement(By.id("selectbox"));
Select currentSelect = new Select(currentElement);
currentSelect.selectByVisibleText(updatedValue);
currentElement.sendKeys(Keys.TAB);
System.out.println("milestoneA");
if ((exceptionExpected()) {
System.out.println("milestoneB");
wait.until(ExpectedConditions.alertIsPresent());
System.out.println("milestoneC");
checkAlertBox(getExpectedResultFromExcel());
}
In DEBUG mode, the code keeps going fine and all is good. In RUN mode in my logs I get up to milestoneB and then the above mentioned error is thrown.
Further to this, if I add a Thread.sleep(1000) before Tabbing, all works fine.
Any ideas please?
I would try to send the TAB key until the element loses the focus:
WebElement currentElement = driver.findElement(By.id("selectbox"));
currentElement.click();
currentElement.sendKeys("abcd");
// wait for the popup to be visible
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#abc")));
// send the TAB key while the current element has focus
new WebDriverWait(driver, 20).until((WebDriver wd) -> {
currentElement.sendKeys(Keys.TAB);
return !wd.switchTo().activeElement().equals(currentElement);
});

How to click on a button with force using java selenium web driver

I am using selenium web driver with java.
And developing automation for my app in facebook, so whenever I add my app for first time in facebook, it is asking for permissions with okay button
I am trying to click on okay button with my code but that is not working.
Is there a better way to click on okay button using selenium web driver with java?
What I tried is:
1)driver.findElemenr(element).click();
2)Actions action = new Actions(driver);
action.click(element)
3)Actions action = new Actions(driver);
action.moveToElement(element).click()
4)Actions action = new Actions(driver);
action.KeyDown(element, Keys.ENTER);
Please let me know the reason before if you want to downvote my question
I think you are looking for isEnabled() method in Selenium. What you can do is, after you click the button using webdriver you can check the status of the button and repeat the click process if the button is still enabled.
You just try with logic something like below.
int i=0;
while(isElementPresent(button) && i<10)
{
Thread.sleep(1000);
driver.findElement(button).click();
i++;
}
The above code will try to click on button until it present or i (int i)reached 10. (loop breaking point)
You can find isElementPresent method implementation here.
you can try this,
WebDriverWait button = new WebDriverWait(driver,60);
button.until(ExpectedConditions.elementToBeClickable(element));
button.click();
This will wait 60 secs for the button to be clickable,if condition (element is clickable) is met before 60 secs, well and good, button will be clicked, else an exception will be thrown...
ExpectedConditions class provides many useful methods.

Selenium Java open new window, close it, and control main window again

I find my question to be different than everything that I've searched for because I need to open a new window in my code (not from clicking a link in a UI). So i already have a driver handling my only window, and then I do this:
//save the handle of the current (only) window open right now
String MainWindowHandle = driver.getWindowHandle();
//open a new firefox window
driver = new FirefoxDriver();
//in the new window, go to the intended page
driver.navigate().to(foo);
//do some stuff in the pop up window..
//close the popup window now
driver.close();
//switch back to the main window. This is where the error is thrown
driver.switchTo().window(MainWindowHandle);
The error is: "org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died"
What do I need to do to regain control of the initial window?
Thanks in advance.
You don't. If you need to launch a new instance of the browser (which is what this sounds like), then do that.
// "url" is an unused variable, simply included here to demonstrate
// that the driver variable is valid and capable of being used.
String url = driver.getCurrentUrl();
// Open a new Firefox window
// Note that here, in your original code, you've set the
// driver variable to another instance of Firefox, which
// means you've orphaned the original browser.
WebDriver driver2 = new FirefoxDriver();
// In the new window, go to the intended page
driver2.navigate().to(foo);
// Do some stuff in the pop up window..
// Close the popup window now
driver2.quit();
// No need to switch back to the main window; driver is still valid.
// Remember that "url" is simply a dummy variable used here to
// demonstrate that the initial driver is still valid.
url = driver.getCurrentUrl();

selenium, how can I select new window

I run my selenium rc test in Eclipse with TestNG. I have a link which tries to open a new browser page. How can I select this new page to operate in? I use this code:
selenium.selectWindow("name=NewPage");
however it says page not found. I also try to define page ids or titles with this code:
String[] wins = selenium.getAllWindowIds();
for (String s : wins)
System.out.println("win: " + s);
It does not define my new opened window:
win: MainPage
win:
If use selenium.getAllWindowNames() I get win: selenium_main_app_window
win: selenium_blank65815.
I write this code selenium.selectWindow("name=blank99157"); but get the error - ERROR: Window does not exist. If this looks like a Selenium bug, make sure to read http://seleniumhq.org/docs/02_selenium_ide.html#alerts-popups-and-multiple-windows for potential workarounds.
The window obviously has no name, so you can't select it by name.
If the window is opened via JavaScript and you can change the script, try changing window.open("someUrl"); to window.open("someUrl", "someName");, you'll be then able to select the window by the set name. More information on the MDN doc for window.open().
Selenium RC doesn't support <a href="someUrl" target="_blank"> links (which open the link in a new window). Therefore, if the window is opened by a link of this type, you have to find this <a> element, get the href attribute and call
selenium.openWindow(theFoundUrl, "theNewWindow");
selenium.selectWindow("id=theNewWindow");
If it is opened via JavaScript before or during the onload event, you'll need to call
selenium.openWindow("", "theNewWindow");
selenium.selectWindow("id=theNewWindow");
More information on this in the bug SEL-339 or in the openWindow() and selectWindow() JavaDocs.
If you have only two windows / want to open the newest one, you can try
selenium.selectPopup()
That is, obviously, the easiest way, because it selects the first non-top window. Therefore, it's only useful when you want to select the newest popup.
If the new window has a unique title, you can do
selenium.selectPopup("Title of the window");
or selenium.selectWindow("title=Title of the window");
Otherwise, you must iterate over selenium.getAllWindowNames() to get the right name (Selenium creates names for windows without one). However, you can't hardcode that name into your testcase, because it will change every time, so you'll need to work out some dynamic logic for this.
You won't like this: Go for WebDriver. It should be far more resistant to such problems.
WebDriver driver = new FirefoxDriver();
WebElement inputhandler = driver.findelement(By.linktext("whatever here"));
inputhandler.click();
String parentHandle = driver.getWindowHandle();
Set<String> PopHandle = driver.getWindowHandles();
Iterator<String> it = PopHandle.iterator();
String ChildHandle = "";
while(it.hasNext())
{
if (it.next() != parentHandle)
{
ChildHandle = it.next().toString();
// because the new window will be the last one opened
}
}
driver.switchTo().window(ChildHandle);
WebDriverWait wait1 = new WebDriverWait(driver,30);
wait1.until(ExpectedConditions.visibilityOfElementLocated(By.id("something on page")));
// do whatever you want to do in the page here
driver.close();
driver.switchTo().window(parentHandle);
You might not be using the correct window ID.
Check out this link. You might find your answer here.
Let me know you this helps.
Try selenium.getAllWindowNames(), selenium.getAllWindowTitles()..one of them will work for sure.

Webdriver showModalDialog

We are using webdriver for our functional tests. But our application uses the showModalDialog JS function a lot to open a popup. When we try to test this functionality with webdriver it hangs from the moment the popup is opened.
We tried several things to test this:
Using the workaround explained here. But this seems to be a fix for selenium and not for webdriver. We tried it but it didn't work.
Searching for a good alternative, HtmlUnit opened the modal dialog and could interact with it, but it has it's drawbacks like no visual help to fix certain tests and it stopped execution when it detected a JS error in a JS library we have to use but have no control over.
How can we test this or work around this problem?
From my experiences with various automation tools interaction with "webpage dialog" windows opened from IE using window.showModalDialog() or window.showModelessDialog() is not available.
Since the window is not a "true" window (look at the taskbar, it doesn't even show up) most tools can't "inspect" it and/or interact with it.
However if you do find a tool that will, please advise - there are many people looking for such a beast.
That all said, if you can possibly avoid using either of these 2 proprietary methods you'll have much more luck.
(and yes, for the picky ones, Firefox and Chrome have adopted these kind of dialogs but they don't work quite the same)
None of the answers answer the question. If the driver hangs, then you can't call any methods on it. The question is NOT about finding the pop up, it is about how to stop the driver hanging. The only way I have found is to not use showModalDialog. This can be done by adding the folowing to your test code :
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
which calls window.open each time your JavaScript calls window.showModalDialog.
I am using webdriver.SwitchTo().Window() method but my concern is my popup window does not have "Name"
When I use webdriver.WindowHandles it return only one handle, I am using this statement after popup window open.
As I don't have name / handle I cannot switch from parent window to child window.
Any other solution to do the same functionality
First we have to switch to the active element:
driver.switchTo().activeElement();
To check whether we have actually switched to the correct active element:
driver.switchTo().activeElement().getText();
Even if the window doesn't have name u can use
driver.switchTo.defaultcontent();
and perform the operation you want to execute
or else you can get the window handle name using the below command
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle); }
hope this should work for you.
Issue 284 is for WebDriver. It seems that it will be implemented only after Issue 27 will be implemented, so the fix should be in Beta 1 or 2 of WebDriver.
Set<String> beforePopup = driver.getWindowHandles();
Set<String> afterPopup = driver.getWindowHandles();
afterPopup.removeAll(beforePopup);
if(afterPopup.size()==1){
System.out.println(afterPopup.toArray()[0]);
}
driver.switchTo().window((String) afterPopup.toArray()[0]);
What I have been using and it works great for us on with IE and Firefox is to go through popups
and look for a a unique text on the popup you are trying to interact with. Here is the method, let me know if it works for you. Please note the line driver = driver.switchTo().window(windowHandle);
public void switchWindow(String containingText, WebDriver driver) throws Exception {
if ( StringUtils.isEmpty(containingText))
return;
int counter = 1;
int numOfpopups = driver.getWindowHandles().size();
System.out.println("Waiting for popup to load..... # handles:" + numOfpopups);
while ( numOfpopups < 2 && ((counter%10) != 0) ) {
counter++;
try{Thread.sleep(1000);}catch (Exception e) {}
}
System.out.println("Done waiting for..... " + counter + " seconds");
if (driver.getWindowHandles().size() < 2)
throw new BrowserException("Timeout after " + counter + " secs. No popup present. ");
System.out.println("Going through window handles...");
for (String windowHandle : driver.getWindowHandles()) {
driver = driver.switchTo().window(windowHandle);
if ( driver.getPageSource().contains(containingText)
return;
else
continue;
}
throw new Exception("Window containing text '" + containingText + "' not found");
}
To my knowledge, webdriver has no built-in functionality to handle modal windows as of now. Webdriver will hang once you click button which opens modal window. This happens due to JS on parent window halts until child window is closed.
To handle modal windows such as this one, see below for possible workaround written in Java. The main idea is to perform action that opens modal window (click on the button) in new thread.
/**
* Click button to open modal window and switch to it
* #param we webElement handle of a button
*/
public void clickToOpenModal(final WebElement we) {
//Get handles of all opened windows before opening modal window
Set<String> initWindowHandles = getDriverInstance().getWindowHandles();
//Create new thread and click button to open window
Thread thread1 = new Thread() {
#Override
public void run() {
//Click button
click(we);
}
};
thread1.start();
//Wait for window to appear
waitForWindow(initWindowHandles, pauseL);
thread1.interrupt();
thread1 = null;
//Get handles of all opened windows after opening modal window
Iterator<String> it = getDriverInstance().getWindowHandles().iterator();
//Select handle of modal window
String windowHandle = "";
while(it.hasNext()){
windowHandle = it.next();
}
//Switch focus and work on the modal window
getDriverInstance().switchTo().window(windowHandle);
}
The solution by Hugh Foster works, i tried this and succeeded
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
You can find the url of modal dialog then open it on another tab, it will work as normal.
In case you want to deal with open modal dialog, you can try to send "tab" key for move around objects and "send keys... enter" for setText or click.
Note: Below is some information why you cannot use selenium webdriver for work with that modal.
Modal pop-up - This is very specific to IE, Microsoft defined it as
When Windows Internet Explorer opens a window from a modal or modeless HTML dialog box by using the showModalDialog method or by using the showModelessDialog method, Internet Explorer uses Component Object Model (COM) to create a new instance of the window. Typically, the window is opened by using the first instance of an existing Internet Explorer process. When Internet Explorer opens the window in a new process, all the memory cookies are no longer available, including the session ID. This process is different from the process that Internet Explorer uses to open a new window by using the open method.
http://msdn.microsoft.com/en-us/library/ms536759(VS.85).aspx
MSDN blog on Modal dialog
When user select Model popup, parent window is blocked waiting for the return value from the popup window. You will be not able to see the view source of the page, need to close the popup then only the parent window is activated.

Categories

Resources