I want to click on the print button in this page :
https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en
and then save the PDF...
this is the code for click the button:
String url = "https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en";
WebDriver driver = new HtmlUnitDriver();
driver.get(url);
System.out.println(driver.getTitle());
System.out.println(driver.getCurrentUrl());
WebElement element = driver.findElement(By.xpath("//*[@id=\"text-mode-options-header\"]/div/div/div[2]/div[2]/div/button[1]"));
element.click();
System.out.println("Page title is: " + driver.getTitle());
driver.quit();
but I get the following error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate a node using //*[@id="text-mode-options-header"]/div/div/div[2]/div[2]/div/button[1]
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.43.1', revision: '5163bce', time: '2014-09-10 16:27:58'
Driver info: driver.version: HtmlUnitDriver
at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElementByXPath(HtmlUnitDriver.java:1057)
at org.openqa.selenium.By$ByXPath.findElement(By.java:357)
at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1575)
at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.implicitlyWaitFor(HtmlUnitDriver.java:1251)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:1572)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:532)
at com.controlstation.start.Main.main(Main.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
how can I do this using Selenium? is there another way? thanks.
EDIT:
We can click a button with Selenium webdriver in Python using the click method. First, we have to identify the button to be clicked with the help of any locators like id, name, class, xpath, tagname or css. Then we have to apply the click method on it. A button in html code is represented by button tagname.
Here's my insight.
First of all, you need to wait for the page to load in order to interact with the Print
button. The best way to go is to use built-in mechanism: selenium waits - wait for the Print
button to be clickable:
// open print dropdown
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.print-button"))).click();
// click print button
WebElement printButton = driver.findElement(By.cssSelector("button.print-popup-button"));
printButton.click();
Okay, if you run it using ChromeDriver
:
package com.company;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Main {
public static void main(String[] args) {
String url = "https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en";
WebDriver driver = new ChromeDriver();
driver.get(url);
// open print dropdown
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.print-button"))).click();
// click print button
WebElement printButton = driver.findElement(By.cssSelector("button.print-popup-button"));
printButton.click();
// now what?
}
}
You'll see the Chrome Print Preview dialog, which is, unfortunately, out of scope for selenium:
But, there is a hope, if you examine available Chrome arguments, you would see that there is the relevant one:
--disable-print-preview - Disables print preview (For testing, and for users who don't like us. :[ )
Okay, let's try it out:
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-print-preview");
WebDriver driver = new ChromeDriver(options);
driver.get(url);
Now, there is a system print dialog being shown:
Selenium cannot control it too. So, nope, there is no hope. Oh, wait!
Okay, if we are out of scope of selenium, let's use tools that can help us to click that Print
button in the dialog - Robot
class:
This class is used to generate native system input events for the purposes of test automation, self-running demos, and other applications where control of the mouse and keyboard is needed.
We'll initialize the Robot
and will send Enter
key when the print dialog would show up:
package com.company;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.awt.*;
import java.awt.event.KeyEvent;
public class Main {
public static void main(String[] args) throws AWTException, InterruptedException {
String url = "https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en";
Robot r = new Robot();
r.delay(1000);
WebDriver driver = new ChromeDriver();
driver.get(url);
// open print dropdown
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.print-button"))).click();
// click print button
WebElement printButton = driver.findElement(By.cssSelector("button.print-popup-button"));
printButton.click();
Thread.sleep(2000);
r.keyPress(KeyEvent.VK_ENTER);
r.keyRelease(KeyEvent.VK_ENTER);
}
}
Other options are to use:
sikuli
- you would need an image of the print button in order for sikuli to locate it and clickautoit
Also see:
This way you can click the Print including maps
-option (sorry, but it is in C#):
Actions builder = new Actions(Driver);
builder.MoveToElement(Driver.FindElement(By.ClassName("print-button"))).Click()
.MoveToElement(Driver.FindElements(By.ClassName("print-popup-button"))[0]).Click().Build().Perform();
But! In your question you had a picture of Chrome print preview window, which I think won't be available with HtmlUnitDriver, which your code is using. You can always run the test with chromedriver, but it seems like the print preview is out of scope for selenium, ie. you can't control it with webdriver. To my knowledge the same is true for system print dialog, which appears with firefox. If HtmlUnitDriver behaves differently in this case, then you'll be fine, but I'm afraid you are going to face a problem here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With