Waits in Selenium WebDriver

Different wait commands in selenium:
In selenium "Waits" play an important role in executing tests. Selenium waits can be classified as below, we will discuss each wait in detail:
Classification of Selenium Waits
Why do we need waits in Selenium?
Most web applications are developed with Ajax and Javascript. When a page loads on a browser, the various web elements that someone wants to interact with may load at various time intervals.
This obviously creates difficulty in identifying any element. On top of that, if an element is not located then the “ElementNotVisibleException/NoSuchElementException” appears.

Please have a look at below image:

In above web page we have a button 'Click Me', after clicking on that button, a message appears after waiting for 5 seconds.
Page Link: https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html
Let's consider this scenario and write a script without using any waiting commands in selenium.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Demo1 {

 public static void main(String[] args) {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  driver.findElement(By.id("testWait123")).click();
  WebElement ele=driver.findElement(By.xpath("//div[text()='Welcome To Automation Testing Insider']"));
  String text=ele.getText();
  System.out.println("The msg is: "+text);
  driver.close();
 }
}

Output:
Starting ChromeDriver 79.0.3945.36 (3582db32b33893869b8c1339e8f4d9ed1816f143-refs/branch-heads/3945@{#614}) on port 16094
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
Feb 21, 2020 3:22:49 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//div[text()='Welcome To Automation Testing Insider']"}
  (Session info: chrome=79.0.3945.130)
For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:48'
System info: host: 'HITENDRA-PC', ip: '169.254.161.182', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_162'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 79.0.3945.130, chrome: {chromedriverVersion: 79.0.3945.36 (3582db32b3389..., userDataDir: C:\Users\Hitendra\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:59460}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify}
Session ID: b49a3b9faf99bfbcc99834650e0182ff
*** Element info: {Using=xpath, value=//div[text()='Welcome To Automation Testing Insider']}
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
 at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
 at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
 at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
 at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
 at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
 at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
 at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:323)
 at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:428)
 at org.openqa.selenium.By$ByXPath.findElement(By.java:353)
 at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315)
 at WaitsDemo.Demo1.main(Demo1.java:20)


So you can see in the above program we got 'NoSuchElementException' if we do not use wait commands in such scenarios. Now lets talk about Synchronization and later on we will handle the above scenario using different wait commands.

Basically in Test Automation, we have two components:
  •  Application Under Test
  •  Test Automation Tool
Both these components will have their own speed. We should write our scripts in such a way that both the components should move with same and desired speed, so that we will not encounter "Element Not Found" errors.

So Synchronization  is a mechanism which involves more than one components to work parallel with Each other.

Synchronization can be classified into two categories:
  •  Unconditional – Thread.sleep() wait
  •  Conditional Synchronization – Implicit, Explicit and Fluent wait
Why use wait commands?
Wait commands direct test scripts to pause for a certain time before throwing exceptions.
Selenium WebDriver provides three commands to implement wait in tests.

Implicit Wait - Implicit waits are used to provide a default waiting time (say 30 seconds) between each consecutive test step/command across the entire test script. Implicitly wait is applied globally, which means it is always available for all the web elements throughout the driver instance. It implies that if the driver is interacting with 100 elements, then implicitly wait is applicable for all the 100 elements.

Syntax: driver.manage().timeouts().implicitlyWait(4,TimeUnit.SECONDS);

Please consider the below program code and usage of implicitly code.
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Demo3 {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  driver.findElement(By.id("testWait123")).click();
  WebElement ele = driver.findElement(By.xpath("//div[text()='Welcome To Automation Testing Insider']"));
  String text = ele.getText();
  System.out.println("The msg is: " + text);
  driver.close();
 }
}

Output
The msg is: Welcome To Automation Testing Insider

In the above code, I have given an implicit wait at 30 seconds, which implies that the maximum wait time is 30 seconds for the particular element to load or to arrive at the output. Implicit wait is a dynamic wait.
What are dynamic waits?
Implicit, Explicit, and Fluent waits are dynamic waits.  Consider a situation where you have given a TimeOut value of 30 seconds. If the element is loaded in 5 seconds, then rest 25 seconds will be ignored. It won’t wait until the TimeOut value is completed, i.e 30 seconds. That’s why all waits are considered as dynamic waits.

Explicit Wait - Explicit waits are used to halt the execution until the time a particular condition is met or the maximum time has elapsed. Explicit waits are a concept from the dynamic wait, which waits dynamically for specific conditions. It can be implemented by the WebDriverWait class. To understand the explicit wait in Selenium WebDriver, you should know the requirements and why we use wait statements in programs.

In order to declare explicit wait, one has to use “ExpectedConditions”. The following Expected Conditions can be used in Explicit Wait.

alertIsPresent()
elementSelectionStateToBe()
elementToBeClickable()
elementToBeSelected()
frameToBeAvaliableAndSwitchToIt()
invisibilityOfTheElementLocated()
invisibilityOfElementWithText()
presenceOfAllElementsLocatedBy()
presenceOfElementLocated()
textToBePresentInElement()
textToBePresentInElementLocated()
textToBePresentInElementValue()
titleIs()
titleContains()
visibilityOf()
visibilityOfAllElements()
visibilityOfAllElementsLocatedBy()
visibilityOfElementLocated()

Syntax:
WebDriverWait wait= new WebDriverWait(driver, 5);
        WebElement ele=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(“xpath")));

Example – Suppose I have a web page that has some login form, and after login, it takes a lot of time to load the account or home page. This page is dynamic — it means that sometimes it takes 10 seconds to load the homepage, and sometimes, it’s 15 seconds and so on. In such situations, explicit wait helps us to wait until a specific page is not present.

Please refer below example code, here we have created an object of WebDriver wait and passed the driver reference and timeout as parameters. However in below example i have created user defined method findElement which we can use for any web elements.
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 Demo4 {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  driver.findElement(By.id("testWait123")).click();
  String xpath="//div[text()='Welcome To Automation Testing Insider']";
  WebElement ele=findElement(driver,xpath,10);
  String text = ele.getText();
  System.out.println("The msg is: " + text);
  driver.close();
 }
 
 public static WebElement findElement(WebDriver driver1, String xpath1, int timeout) {
  WebElement ele=new WebDriverWait(driver1, timeout).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath1)));
  return ele;
 }
}

Output:
The msg is: Welcome To Automation Testing Insider

Fluent Wait - The Fluent Wait command defines the maximum amount of time for Selenium WebDriver to wait for a certain condition to appear. It also defines the frequency with which WebDriver will check if the condition appears before throwing the “ElementNotVisibleException”.


Syntax:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(40))
.pollingEvery(Duration.ofSeconds(8))
.ignoring(Exception.class);

   WebElement ele = wait.until(new Function<WebDriver, WebElement>() {
     public WebElement apply(WebDriver driver) {
       return driver.findElement(By.xpath(“xpath"));
     }
   });

Example: Let's consider a scenario where an element is loaded at different intervals of time. The element might load within 10 seconds, 20 seconds or even more then that if we declare an explicit wait of 20 seconds. It will wait till the specified time before throwing an exception. In such scenarios, the fluent wait is the ideal wait to use as this will try to find the element at different frequency until it finds it or the final timer runs out.

Please refer below example code:
import java.time.Duration;
import java.util.function.Function;
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.FluentWait;
import org.openqa.selenium.support.ui.Wait;

public class Demo5 {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  driver.findElement(By.id("testWait123")).click();
  String xpath="//div[text()='Welcome To Automation Testing Insider']";
  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(Duration.ofSeconds(20))
    .pollingEvery(Duration.ofSeconds(2))
    .ignoring(Exception.class);

       WebElement ele = wait.until(new Function<WebDriver, WebElement>() {
         public WebElement apply(WebDriver driver) {
           return driver.findElement(By.xpath(xpath));
         }
       });
  String text = ele.getText();
  System.out.println("The msg is: " + text);
  driver.close();
 }
}

Output
The msg is: Welcome To Automation Testing Insider

Some other waits are: 
PageLoadTimeOut - One of the timeouts is focused on the time a webpage needs to be loaded – the pageLoadTimeout limits the time that the script allots for a web page to be displayed. Page load timeout is useful when we perform a performance test. Page Load timeout is applicable only to driver.get() and driver.navigate().to() methods in selenium.

Syntax:  driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

Consider below example where we used PageLoadTimeOut to limit the page to be loaded in 5 seconds but page did not load in 5 seconds and throws TimeoutException exception.
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Demo2 {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  driver.findElement(By.id("testWait123")).click();
  Thread.sleep(5000);
  WebElement ele = driver.findElement(By.xpath("//div[text()='Welcome To Automation Testing Insider']"));
  String text = ele.getText();
  System.out.println("The msg is: " + text);
  driver.close();
 }
}

Output
Starting ChromeDriver 79.0.3945.36 (3582db32b33893869b8c1339e8f4d9ed1816f143-refs/branch-heads/3945@{#614}) on port 31941
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
Feb 21, 2020 3:51:50 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
[1582280516.761][SEVERE]: Timed out receiving message from renderer: 0.015
[1582280516.791][SEVERE]: Timed out receiving message from renderer: -0.031
Exception in thread "main" org.openqa.selenium.TimeoutException: timeout
  (Session info: chrome=79.0.3945.130)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:48'
System info: host: 'HITENDRA-PC', ip: '169.254.161.182', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_162'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 79.0.3945.130, chrome: {chromedriverVersion: 79.0.3945.36 (3582db32b3389..., userDataDir: C:\Users\Hitendra\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:59888}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify}
Session ID: 2465cdde761b595d659c73ff38c7aa58
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
 at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
 at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
 at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
 at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
 at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
 at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
 at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:277)
 at WaitsDemo.Demo2.main(Demo2.java:20)


Thread.sleep() - Sleep is a static method that belongs to the thread class. This method can be called using the reference of the class name i.e Thread. If you use Thread.sleep while performing automation testing with Selenium, then this method will stop the execution of the script for the specified duration of time, irrespective of whether the element is found or not on the web page.

Syntax: Thread.sleep(5000);
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Demo2 {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  driver.findElement(By.id("testWait123")).click();
  Thread.sleep(10000);
  WebElement ele = driver.findElement(By.xpath("//div[text()='Welcome To Automation Testing Insider']"));
  String text = ele.getText();
  System.out.println("The msg is: " + text);
  driver.close();
 }
}

Output
The msg is: Welcome To Automation Testing Insider

Consider the above example, the element will be visible in 5 seconds but WebDriver will still wait for another 5 seconds. It will increase test execution time.

Difference between Implicit wait and Explicit wait:


What happens when we use Implicit wait and Explicit wait together:

Implicit wait destroys meaning of using explicit wait when using together. So it is advised not to use implicit wait and explicit wait together. Actually when we use both waits together, both waits will be applied at the same time and it get messed up.

Now we will see reason behind these using below scenarios:

1. Explicit Wait= Implicit Wait (Say 10 seconds)

Both waits get activated at same time to locate element. Explicit wait keeps searching for an element till it is found and implicit wait allows webdriver to search till timeout. When explicit wait starts and looks for element, because of implicit wait it needs to wait for 10 seconds because element is not found. So both waits completes 10 seconds wait time.

2. Implicit wait(20) > Explicit Wait(10)

When explicit wait stars looking for element, it needs to wait for 20 seconds because of implicit wait time.

3. Implicit wait(10) < Explicit Wait(20)

When explicit wait starts looking for element, it needs to wait for 10 seconds because of implicit wait. After that implicit wait throws exception because of not able to locate element.  Exception stops explicit wait to search further and does not allow to reach its timeout.

Few more points to remember:
1. The most widely used waits are implicit and explicit waits. Fluent waits are not preferable for real-time projects.
2. We use FluentWait commands mainly when we have web elements which sometimes visible in few seconds and some times take more time than usual. Mostly in Ajax applications.
3. We use mostly explicit wait because it is for specific condition/element and we have more flexibility in using explicit rather than implicit.

Please do watch below video to understand usage of different waits in selenium webdriver.


Visit our YouTube Channel. SUBSCRIBE channel for upcoming topics on Selenium WebDriver.

Handling iFrames in Selenium Webdriver: switchTo()

What is an Iframe or frame?
 An iframe is also known as the inline frame. It is a tag used in HTML5 to embed an HTML document within a parent HTML document. An iframe tag is defined using <iframe></iframe> tags.
IFrame is a web page which is embedded in another web page or an HTML document embedded inside another HTML document.

The frame enables a developer to split the screen horizontally or vertically by using the frameset tag. Frame and frameset tags are deprecated as they are no longer supported by HTML 5.

How to Identify the Iframe?
  • Right click on the element, If you find the option like View Frame Source' then it is an iframe.
  • From DOM tree. Search with tag ‘iframe’
  • Right click on the page and click 'View Page Source' and Search with the 'iframe‘
  • Through selenium locator tagName in the script  -- By.tagName("iframe")
To work with different frames, we need to use the SwitchTo().frame method. This method enables the browser to switch between multiple frames. It can be implemented in the following ways:

switchTo.frame(int  frame number): Defining the frame index number, the Driver will switch to that specific frame
switchTo.frame(string  frameNameOrId): Defining the frame element or Id, the Driver will switch to that specific frame
switchTo.frame(WebElement  frameElement): Defining the frame web element, the Driver will switch to that specific frame.

Selenium Script on iframe:

import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class IframeDemo {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  Thread.sleep(2000);
  //First finding the elements using any of locator strategy
  List<WebElement> iframList = driver.findElements(By.tagName("iframe"));
  int totalFrames = iframList.size();
  System.out.println("No of Frames:" + totalFrames);
  WebElement ele=driver.findElement(By.name("iframe_b"));
  System.out.println("Frame Names are:");
  for (WebElement iframe : iframList) {
   System.out.println(iframe.getAttribute("name"));
   if (iframe.getAttribute("name").equals("iframe_b")) {
    //switch to frame by element
    driver.switchTo().frame(ele);
    //Perform all the required tasks 
    driver.findElement(By.id("searchInput")).sendKeys("iframe Testing");
    Thread.sleep(2000);
    //Switching back to the main window
                driver.switchTo().defaultContent();
   }
  }
  boolean btnDisplayed=driver.findElement(By.id("simpleAlert")).isDisplayed();
  System.out.println(btnDisplayed);
  driver.close();
 }
}

Please refer below YouTube video to get more details:


Handle multiple windows in Selenium WebDriver

In this article, we will see how to handle multiple windows using Selenium WebDriver. In real time, we face many scenarios, where an application throws multiple popups. We can easily achieve this using Windows Handles in Selenium WebDriver. We use ‘Switch To’ method which allows us to switch control from one window to other.

What is a window handle?
A window handle is a unique identifier that holds the address of all the windows. This is basically a pointer to a window, which returns the string value. This window handle function helps in getting the handles of all the windows. It is guaranteed that each browser will have a unique window handle.

Methods and Commands:
get.windowhandle(): helps in getting the window handle of the current window
get.windowhandles(): helps in getting the handles of all the windows opened
set: helps to set the window handles which is in the form of a string. 
set<string> set=driver.get.windowhandles();
switch to: helps in switching between the windows
action: helps to perform certain actions on the windows.

Please refer complete program below:

import java.util.Iterator;
import java.util.Set;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WindowHandle1 {

 public static void main(String[] args) throws InterruptedException {

  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  // To open Naukri.com with multiple windows
  driver.get("https://www.naukri.com/");
  Thread.sleep(2000);
  // It will return the parent window name as a String
  String parentWinID = driver.getWindowHandle();
  System.out.println("Parent Win ID is: " + parentWinID);
  // It returns no. of windows opened by WebDriver and will return Set of Strings
  Set<String> allWinID = driver.getWindowHandles();
  System.out.println("Total Window size:" +allWinID.size());
  System.out.println("All win IDs are:");
  for (String allIDs : allWinID) {
   System.out.println(allIDs);
  }
  // Using Iterator to iterate with in windows
  Iterator<String> itr = allWinID.iterator();
  while (itr.hasNext()) {
   String childWinID = itr.next();
   // Compare whether the main window is not equal to child window. If not equal, we will close child windows.
              if(!parentWinID.equalsIgnoreCase(childWinID)) {
               driver.switchTo().window(childWinID);
               System.out.println("Child URL is:"+driver.getCurrentUrl());
               System.out.println("Child Win Title is:"+driver.getTitle());
               Thread.sleep(2000);
               driver.close();
              }
  }
  // This is to switch to the main window
  driver.switchTo().window(parentWinID);
  driver.quit();
 }
}

Please refer below YouTube video to get more details:
Below scenarios covered in this video:

  •  How to get total windows and print them. 
  •  How to switch to child window and perform action.
  •  Come back (switch) to parent window.
  •  Create a Program (Library) which will handle multiple windows.
  •  Create a Program (Library) which will handle different tabs.
  •  How to switch through index.

Different ways of Scrolling in Selenium WebDriver

What is Scroll and Scroll bar?
A vertical or horizontal bar commonly located on the far right or bottom of a window that allows you to move the window viewing area up, down, left, or right
Selenium Webdriver does not require scroll to perform actions as it manipulates DOM. But in certain web pages, elements only become visible once the user have scrolled to them. In such cases scrolling may be necessary.

To scroll using Selenium, you can use JavaScriptExecutor interface that helps to execute JavaScript methods through Selenium Webdriver.
JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript(Script,Arguments);
  • Scroll up or down by pixel
js.executeScript("window.scrollBy(1000,4000)")

Please refer below program:
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ScrollUpDown {

 public static void main(String[] args) throws InterruptedException {
  
  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.get("https://www.automationtestinginsider.com/");
  Thread.sleep(2000);
  JavascriptExecutor js= (JavascriptExecutor) driver;
  js.executeScript("window.scrollBy(1000,0)");
 }
}
  • Scroll down by Visibility of Element
js.executeScript("arguments[0].scrollIntoView();", ele);

Please refer below program:

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class ScrollDownByVisibilityOfEle {

 public static void main(String[] args) throws InterruptedException {
  
  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  Thread.sleep(2000);
  JavascriptExecutor js= (JavascriptExecutor) driver;
  WebElement ele=driver.findElement(By.id("simpleAlert"));
  js.executeScript("arguments[0].scrollIntoView()",ele );
 }
}
  • Scroll down by end of the page
js.executeScript("window.scrollTo(0, document.body.scrollHeight)");

Please refer below program:
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ScrollDownByEndOfthePage {

 public static void main(String[] args) throws InterruptedException {
  
  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  Thread.sleep(2000);
  JavascriptExecutor js= (JavascriptExecutor) driver;
  js.executeScript("window.scrollTo(0, document.body.scrollHeight)");
 }
}

Please refer below YouTube video to get more details:

Upload and Download file in Selenium

There are different ways to upload files in Selenium like:
  •       Using sendkeys() method
  •       Using AutoIT tool
  •       Using Robot Class
Using sendKeys() method:
Uploading files in WebDriver is done by simply using the sendKeys() method on the file-select input field to enter the path to the file to be uploaded.
Let's say we wish to upload the file "C:\\Users\\Hitendra\\Desktop\\TestFile.txt". Our WebDriver code should be like the one shown below.
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.interactions.Actions;

public class UploadFileUsingSendkeys {

 public static void main(String[] args) throws InterruptedException {
  
  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  Thread.sleep(2000);
  Actions act= new Actions(driver); 
  WebElement chooseFile=driver.findElement(By.id("fileupload1"));
  act.moveToElement(chooseFile).perform(); 
  Thread.sleep(1000); 
  chooseFile.sendKeys("C:\\Users\\Hitendra\\Desktop\\TestFile.txt");
 }
}

Using AutoIT tool:
(refer YouTube video on Introduction to AutoIT tool --https://www.youtube.com/watch?v=be05PN2XW3k&list=PLsGOlyTzNH6f_pZuGZDFjI5IeCWGQqiwF&index=32 )

We need three tools in order to upload file using selenium.

  • Selenium Webdriver
  • AutoIT editor and element identifier
  • The window that you want to automate
Open AutoIT script editor,and start writing a script for selecting a file to upload.

There are lots of method available which we can use in a script according to the requirement, but right now we will focus on the below methods as these methods are required for writing file upload script:

ControlFocus(" title "," text ",controlID ) //Sets input focus to a given control on a window.
ControlSetText(" title "," text ",controlID ," File path which need to upload " ) // Sets text of a control.
ControlClick(" title "," text ",controlID ) //Sends a mouse click command to a given control.

Refer below Image:
Sample AutoIT Script
Please refer below YouTube video (at the end of this article)  on how to upload file using AutoIT tool.

Complete program to upload file using AutoIT tool in Selenium:

import java.io.IOException;
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.interactions.Actions;

public class UploadUsingAutoIT {

 public static void main(String[] args) throws InterruptedException, IOException {
  
  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  Thread.sleep(2000);
  Actions act= new Actions(driver); 
  WebElement chooseFile=driver.findElement(By.id("fileupload1"));
  act.moveToElement(chooseFile).click().perform();
  Thread.sleep(2000);
  Runtime.getRuntime().exec("C:\\Users\\Hitendra\\Desktop\\UploadFile.exe");
 }
}

Using Robot Class:
We have discussed uploading a file using using Webdriver Sendkeys method and Using AutoIT Tool. Now here we will look into an other way of doing file upload using Robot class and StringSelection class in java.

In certain Selenium Automation Tests, there is a need to control keyboard or mouse to interact with OS windows like Download pop-up, Alerts, Print Pop-ups, etc. or native Operation System applications like Notepad, Skype, Calculator, etc.

Selenium Webdriver cannot handle these OS pop-ups/applications. In Java version 1.3 Robot Class was introduced. Robot Class can handle OS pop-ups/applications.

Robot class is a separate class in Java which will allow us to perform multiple tasks based on our requirement. It generally will throw AWT exception so we need to deal with it accordingly. Using Robot class, we can simulate keyboard event in Selenium. To use keyboard events you have to use to a method of Robot class.
Robot class is used to (generate native system input events) take the control of mouse and keyboard. Once you get the control, you can do any type of operation related to mouse and keyboard through with java code.

There are different methods which robot class uses. Here in the below example we have used 'keyPress' and 'keyRelease' methods.

keyPress - takes keyCode as Parameter and Presses here a given key.
keyrelease - takes keyCode as Parameterand Releases a given key

We will follow below steps:
Step 1- We have to copy the file location in system clipboard.
Step 2- We have to click on upload button and use CTR+V and ENTER.
Note- Robot class each key has to press and release respectively

Complete program given below

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
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.interactions.Actions;

public class UploadFileUsingRobot {

 public static void main(String[] args) throws InterruptedException, AWTException {
  
  WebDriver driver;
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
  driver = new ChromeDriver();
  driver.manage().window().maximize();
  driver.get("https://www.automationtestinginsider.com/2019/08/textarea-textarea-element-defines-multi.html");
  Thread.sleep(2000);
  Actions act= new Actions(driver);
  WebElement chooseFile=driver.findElement(By.id("fileupload1"));
  act.moveToElement(chooseFile).click().perform();
  Thread.sleep(2000);
  uploadFile("C:\\Users\\Hitendra\\Desktop\\TestFile.txt");
 }
 
 public static void setClipBoard(String file) {
  StringSelection obj= new StringSelection(file);
  Toolkit.getDefaultToolkit().getSystemClipboard().setContents(obj, null);
 }
 
 public static void uploadFile(String filePath) throws AWTException {
  setClipBoard(filePath);
  Robot rb= new Robot();
  rb.keyPress(KeyEvent.VK_CONTROL);
  rb.keyPress(KeyEvent.VK_V);
  rb.keyRelease(KeyEvent.VK_CONTROL);
  rb.keyRelease(KeyEvent.VK_V);
  rb.keyPress(KeyEvent.VK_ENTER);
  rb.keyRelease(KeyEvent.VK_ENTER);
 }
}

DownLoadFile file using ChromeOptions Class: Please refer below program to download file on chrome browser using ChromeOptions Class.
import java.util.HashMap;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;

public class DownLoadFile {
 static WebDriver driver;
 public static void main(String[] args) {
  System.setProperty("webdriver.chrome.driver",
    "C:\\Users\\Hitendra\\Downloads\\chromedriver_win32\\chromedriver.exe");
        String downloadFilepath = "C:\\Users\\Hitendra\\Downloads";
        HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
        chromePrefs.put("profile.default_content_settings.popups", 0);
        chromePrefs.put("download.default_directory", downloadFilepath);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", chromePrefs);
        options.addArguments("--test-type");
        options.addArguments("--disable-extensions"); //to disable browser extension popup
        options.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
        driver = new ChromeDriver(options);  
                 driver.get("http://www.seleniumhq.org/download/");
                 driver.findElement(By.linkText("32 bit Windows IE")).click();
 }
}

Please refer below YouTube video to get more details: