This is the next article from the WebDriver Series where I will share with you 30 advanced tips and tricks using Java code. I wrote similar articles separated into 3 parts for C# - part 1, part 2, part 3.
NOTE: This is the second post starting a new ERA for Automate The Planet. This is the second article dedicated to Java. All 250+ publications were related to the .NET world. Of course, I will continue to write C# articles, but I will put Java in the mix.
1. Taking a Screenshot
You can use the following method to take a full-screen screenshot of the browser.
public void takeFullScreenshot(String fileName) throws Exception {
File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
String tempDir = getProperty("java.io.tmpdir");
File destFile = new File(Paths.get(tempDir, fileName + ".png").toString());
FileUtils.getFileUtils().copyFile(srcFile, destFile);
}
Sometimes you may need to take a screenshot of a single element.
public void takeScreenshotOfElement(WebElement element, String fileName) throws Exception {
File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshotFile);
Point point = element.getLocation();
int elementWidth = element.getSize().getWidth();
int elementHeight = element.getSize().getHeight();
BufferedImage eleScreenshot = fullImg.getSubimage(point.getX(), point.getY(), elementWidth, elementHeight);
ImageIO.write(eleScreenshot, "png", screenshotFile);
String tempDir = getProperty("java.io.tmpdir");
File destFile = new File(Paths.get(tempDir, fileName + ".png").toString());
FileUtils.getFileUtils().copyFile(screenshotFile, destFile);
}
First, we make a full-screen screenshot then we locate the specified element by its location and size attributes. After that, the found rectangle chunk is saved as a BufferedImage.
Here is how you use both methods in tests.
@Test
public void takeFullScreenshot_test() throws Exception {
driver.navigate().to("http://automatetheplanet.com");
takeFullScreenshot("testImage");
}
@Test
public void takeElementScreenshot_test() throws Exception {
driver.navigate().to("http://automatetheplanet.com");
var element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[1]/header/div/div[2]/div/div[2]/nav")));
takeScreenshotOfElement(element, "testElementImage");
}
We create a temp file combining the result from the static class Paths and getting the Windows temp folder through getProperty(“java.io.tmpdir”);
2. Get HTML Source of WebElement
You can use the getAttribute method of the WebElement interface to get the inner HTML of a specific element.
@Test
public void getHtmlSourceOfWebElement() {
driver.navigate().to("http://automatetheplanet.com");
var element = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("/html/body/div[1]/header/div/div[2]/div/div[2]/nav")));
String sourceHtml = element.getAttribute("innerHTML");
System.out.println(sourceHtml);
}
While ago, when we were working on the first version of our open-source BELLATRIX test automation framework, I did this research, and afterward, we used many of the tricks in lots of the features of our solution.
3. Execute JavaScript
You can use the interface JavaScriptExecutor to execute JavaScript through WebDriver.
@Test
public void executeJavaScript() {
driver.navigate().to("http://automatetheplanet.com");
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
String title = (String) javascriptExecutor.executeScript("return document.title");
System.out.println(title);
}
This test will take the current window’s title via JavaScript and print it to the output window.
4. Set Page Load Timeout
There are at least three methods that you can use for the job.
First, you can set the default driver’s page load timeout through the WebDriver’s options class.
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
You can wait until the page is completely loaded via JavaScript.
private void waitUntilLoaded() {
wait.until(x -> {
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
String isReady = (String) javascriptExecutor.executeScript("return document.readyState");
return isReady.equals("complete");
});
}
Your third option is to wait for a specific element(s) to be visible on the page.
wait.until(ExpectedConditions.visibilityOfAllElements(
driver.findElements(By.xpath("//\*[@id='tve_editor']/div[2]/div[2]/div/div"))));
5. Execute Tests in a Headless Browser
You can use the ChromeOptions class and set a few arguments to set up Chrome to run without its UI in the so-called headless mode. You can do the same for Firefox and Edge Chromium.
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--headless", "--disable-gpu", "--window-size=1920,1200", "--ignore-certificate-errors");
driver = new ChromeDriver(chromeOptions);
6. Check If an Element Is Visible
You can use the isDisplayed method of the WebElement interface.
@Test
public void checkIfElementIsVisible() {
driver.navigate().to("http://automatetheplanet.com");
var element = driver.findElement(By.xpath("/html/body/div[1]/header/div/div[2]/div/div[2]/nav"); Assert.assertTrue(element).isDisplayed());
}
7. Use Specific Profile
By default, WebDriver always assigns a new ‘clean’ profile if you use the FirefoxDriver default constructor. However, sometimes you may want to fine-tune the profile e.g., add extensions, turn off the JavaScript, etc.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions);
You can do some similar configurations for the ChromeDriver.
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("user-data-dri=C:UsersYour path to userRoamingGoogleChromeUser Data");
driver = new ChromeDriver(chromeOptions);
8. Turn Off JavaScript
You can use the code from point 7 to set up a new Firefox profile. Then you need to set the ‘javascript.enabled’ preference to false.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
firefoxProfile.setPreference("javascript.enabled", false);
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions);
9. Manage Cookies
Before you can work with the cookies of a site, you need to navigate to some of its pages.
@Test
public void manageCookies() {
driver.navigate().to("http://automatetheplanet.com");
// get all cookies
var cookies = driver.manage().getCookies();
for (Cookie cookie: cookies) {
System.out.println(cookie.getName());
}
// get a cookie by name
var fbPixelCookie = driver.manage().getCookieNamed("\_fbp");
// create a new cookie by name
Cookie newCookie = new Cookie("customName", "customValue");
driver.manage().addCookie(newCookie);
// delete a cookie
driver.manage().deleteCookie(fbPixelCookie);
// delete a cookie by name
driver.manage().deleteCookieNamed("customName");
// delete all cookies
driver.manage().deleteAllCookies();
}
10. Maximize Window
Use the maximize method of the Window interface.
driver.manage().window().maximize
11. Drag and Drop
You can use the special Actions WebDriver class to perform complex UI interactions. Through its method dragAndDropBy, you can drag and drop. You only need to set the desired X and Y offsets.
@Test
public void dragAndDrop() {
driver.navigate().to("http://loopj.com/jquery-simple-slider/");
var element = driver.findElement(By.xpath("//\*[@id='project']/p[1]/div/div[2]"));
Actions action = new Actions(driver);
action.dragAndDropBy(element, 30, 0).build().perform();
}
12. Upload a File
It is a straightforward task to upload a file using WebDriver. You need to locate the file element and use the WebElement’s sendKeys method to set the path to your file.
@Test
public void fileUpload() throws IOException {
driver.navigate().to(
"https://demos.telerik.com/aspnet-ajax/ajaxpanel/application-scenarios/file-upload/defaultcs.aspx");
var element = driver.findElement(By.id("ctl00_ContentPlaceholder1_RadUpload1file0"));
String filePath = Paths.get(getProperty("java.io.tmpdir"), "debugWebDriver.xml").toString();
File destFile = new File(filePath);
destFile.createNewFile();
element.sendKeys(filePath);
}
13. Handle JavaScript Pop-ups
You can use the accept and dismiss methods of the Alert interface to handle JavaScript pop-ups. First, you need to use the switchTo method to switch to the alert.
@Test
public void handleJavaScripPopUps() {
driver.navigate().to("http://www.w3schools.com/js/tryit.asp?filename=tryjs_confirm");
driver.switchTo().frame("iframeResult");
var button = driver.findElement(By.xpath("/html/body/button"));
button.click();
Alert alert = driver.switchTo().alert();
if (alert.getText().equals("Press a button!")) {
alert.accept();
} else {
alert.dismiss();
}
}
14. Switch Between Browser Windows or Tabs
WebDriver drives the browser within a scope of one browser window. However, we can use its switchTo method to change the target window or tab.
@Test
public void movingBetweenTabs() {
driver.navigate().to("https://www.automatetheplanet.com/");
var firstLink = driver.findElement(By.xpath("//_[@id='menu-item-11362']/a"));
var secondLink = driver.findElement(By.xpath("//_[@id='menu-item-6']/a"));
String selectLinkOpenninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
firstLink.sendKeys(selectLinkOpenninNewTab);
secondLink.sendKeys(selectLinkOpenninNewTab);
Set < String > windows = driver.getWindowHandles();
String firstTab = (String) windows.toArray()[1];
String lastTab = (String) windows.toArray()[2];
driver.switchTo().window(lastTab);
Assert.assertEquals("Resources - Automate The Planet", driver.getTitle());
driver.switchTo().window(firstTab);
Assert.assertEquals("Blog - Automate The Planet", driver.getTitle());
}
The getWindowHandles method returns all open browser windows. You can pass the name of the desired tab/window to the window method of the TargetLocator interface (returned by the switchTo method) to change the current target.
You can also notice that we use one more trick to open the link in a new tab using the Keys.chord method, and then instead of clicking, we use the sendKeys method to perform CTRL + return sequence.
15. Navigation History
WebDriver Navigation interface contains handy methods for going forward and backward. Also, you can refresh the current page.
@Test
public void navigationHistory() {
driver.navigate().to("https://www.codeproject.com/Articles/1078541/Advanced-WebDriver-Tips-and-Tricks-Part");
driver.navigate().to("http://www.codeproject.com/Articles/1017816/Speed-up-Selenium-Tests-through-RAM-Facts-and-Myth");
driver.navigate().back();
Assert.assertEquals("10 Advanced WebDriver Tips and Tricks - Part 1 - CodeProject", driver.getTitle());
driver.navigate().refresh();
Assert.assertEquals("10 Advanced WebDriver Tips and Tricks - Part 1 - CodeProject", driver.getTitle());
driver.navigate().forward();
Assert.assertEquals("Speed up Selenium Tests through RAM Facts and Myths - CodeProject", driver.getTitle());
}
16. Change User Agent
After you create a new custom Firefox profile, you can set its argument ‘general.useragent.override’ to the desired user agent string.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
firefoxProfile.setPreference("general.useragent.override", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+");
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions);
17. Set HTTP Proxy for Browser
Similar to the user agent configuration, to set a proxy for Firefox, you only need to set a few arguments of the Firefox’ profile.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
firefoxProfile.setPreference("network.proxy.type", 1);
firefoxProfile.setPreference("network.proxy.http", "myproxy.com");
firefoxProfile.setPreference("network.proxy.http_port", 3239);
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions);
18. Handle SSL Certificate Error
8.1. Handle SSL Certificate Error FirefoxDriver
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
firefoxProfile.setAcceptUntrustedCertificates(true);
firefoxProfile.setAssumeUntrustedCertificateIssuer(false);
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions);
8.2. Handle SSL Certificate Error ChromeDriver
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--ignore-certificate-errors");
driver = new ChromeDriver(chromeOptions);
19. Scroll Focus to Control
There isn’t a built-in mechanism in WebDriver to scroll focus to a control. However, you can use the JavaScript’s method window.scroll. You only need to pass the getY location of the desired element.
@Test
public void scrollFocusToControl() {
driver.navigate().to("http://automatetheplanet.com/");
var ourMissionLink = driver.findElement(By.xpath("//\*[@id="
panel - 6435 - 0 - 0 - 4 "]/div"));
String jsToBeExecuted = String.format("window.scroll(0, {0});", ourMissionLink.getLocation().getY());
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
javascriptExecutor.executeScript(jsToBeExecuted);
}
20. Focus on a Control
To do the trick, we use again the special Actions class, which has a method called moveToElement.
@Test
public void focusOnControl() {
driver.navigate().to("http://automatetheplanet.com/");
waitUntilLoaded();
var ourMissionLink = driver.findElement(By.xpath("//\*[@id="
panel - 6435 - 0 - 0 - 4 "]/div"));
Actions action = new Actions(driver);
action.moveToElement(ourMissionLink).build().perform();
}
21. Start FirefoxDriver with Plugins
Just use the addExtension of the FirefoxProfile class to load the desired extension.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
firefoxProfile.addExtension(new File("C:\\extensionsLocation\\extension.xpi"));
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions);
22. Set HTTP Proxy ChromeDriver
The configuration of a proxy for ChromeDriver is a little bit different from the one for FirefoxDriver. You need to use the special Proxy class in combination with ChromeOptions.
var proxy = new Proxy();
proxy.setProxyType(Proxy.ProxyType.MANUAL);
proxy.setAutodetect(false);
proxy.setSslProxy("127.0.0.1:3239");
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setProxy(proxy);
driver = new ChromeDriver(chromeOptions);
23. Set HTTP Proxy with Authentication ChromeDriver
The only difference from the previous example is the configuration of the —proxy-server argument.
var proxy = new Proxy();
proxy.setProxyType(Proxy.ProxyType.MANUAL);
proxy.setAutodetect(false);
proxy.setSslProxy("127.0.0.1:3239");
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setProxy(proxy);
chromeOptions.addArguments("--proxy-server=http://user:password@127.0.0.1:3239");
driver = new ChromeDriver(chromeOptions);
24. Start ChromeDriver with an Unpacked Extension
Chrome extensions can be either packed or unpacked. Packed extensions are a single file with a .crx extension. Unpacked Extensions are a directory containing the extension, including a manifest.json file. To load an unpacked extension you need to set the load-extension argument.
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("load-extension=/pathTo/extension");
driver = new ChromeDriver(chromeOptions);
25. Start ChromeDriver with an Packed Extension
Instead of setting the load-extension argument, you need to use the addExtension method of the ChromeOptions class to set the path to your packed extension.
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addExtensions(new File("local/path/to/extension.crx"));
driver = new ChromeDriver(chromeOptions);
26. Assert a Button Enabled or Disabled
You can check if an element is disabled through the isEnabled method of the WebElement interface.
@Test
public void assertButtonEnabledDisabled() {
driver.navigate().to("http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_button_disabled");
driver.switchTo().frame("iframeResult");
var button = driver.findElement(By.xpath("/html/body/button"));
Assert.assertFalse(button.isEnabled());
}
27. Set and Assert the Value of a Hidden Field
You can get the value of a hidden field through the getAttribute method, part of the WebElement interface. Get the value attribute of the element. You can set the same attribute with a little bit of a JavaScript code.
@Test
public void setHiddenField() {
//<input type="hidden" name="country" value="Bulgaria"/>
var theHiddenElem = driver.findElement(By.name("country"));
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
javascriptExecutor.executeScript("arguments[0].value='Germany';", theHiddenElem);
String hiddenFieldValue = theHiddenElem.getAttribute("value");
Assert.assertEquals("Germany", hiddenFieldValue);
}
28. Wait AJAX Call to Complete Using JQuery
jQuery.active is a variable JQuery uses internally to track the number of simultaneous AJAX requests. Wait until the value of jQuery.active is zero. Then continue with the next operation.
private void waitForAjaxComplete() {
wait.until(x -> {
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
Boolean isAjaxCallComplete =
(Boolean) javascriptExecutor.executeScript("return window.jQuery != undefined && jQuery.active == 0");
return isAjaxCallComplete;
});
}
29. Verify File Downloaded ChromeDriver
To change the default download directory of the current Chrome instance set the download.default_directory argument. When we initiate the file download, we use the WebDriverWait to wait until the file exists on the file system. Finally, we assert the file size. The whole code is surrounded with a try-finally block. In the finally we delete the downloaded file so that our test to be consistent every time.
String downloadFilepath = "c:temp";
HashMap < String, Object > chromePrefs = new HashMap < > ();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", downloadFilepath);
chromeOptions.setExperimentalOption("prefs", chromePrefs);
chromeOptions.addArguments("--test-type");
chromeOptions.addArguments("start-maximized", "disable-popup-blocking");
@Test
public void VerifyFileDownloadChrome() throws IOException {
var expectedFilePath = Paths.get("c:tempTesting_Framework_2015_3_1314_2_Free.exe");
try {
driver.navigate().to("https://www.telerik.com/download-trial-file/v2/telerik-testing-framework");
wait.until(x -> Files.exists(expectedFilePath));
long bytes = Files.size(expectedFilePath);
Assert.assertEquals(4326192, bytes);
} finally {
if (Files.exists(expectedFilePath)) {
Files.delete(expectedFilePath);
}
}
}
30. Verify File Downloaded FirefoxDriver
The code for FirefoxDriver is similar to the one for ChromeDriver. We need to set a few arguments so that the browser not to ask us every time where to save the specified file.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile firefoxProfile = profile.getProfile("xyzProfile");
String downloadFilepath = "c:temp";
firefoxProfile.setPreference("browser.download.folderList", 2);
firefoxProfile.setPreference("browser.download.dir", downloadFilepath);
firefoxProfile.setPreference("browser.download.manager.alertOnEXEOpen", false);
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk",
"application/msword, application/binary, application/ris, text/csv, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream"));
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
WebDriver firefoxDriver = new FirefoxDriver(firefoxOptions); 