What is JavaScript?
JavaScript is a powerful client-side scripting language. Nowadays, most of the web application uses Java Script because of its lightweight nature and to enhance the interaction of a user with the web page and make dynamic web pages.
How to Run JavaScript?
As a Java Script is a scripting language, its can not run its run. For running the script, you need a web browser. When a user requests an HTML page that has Java Script in it, the script is sent to the browser, and when a user interacts with the then, the particular will get executed.
How can we Execute Java Script Manually by Using Browser?
Nowadays, all browser supports Java Script. So we can run the Java Script in any browser by following the below steps:
- Open any browser
- Got to the console tab by pressing the F12 key or right-click and select inspect.
- Type the Java Script in the console tab and hit enter to run the Java Script.
Add Java Screenshot
How does JavaScript help in Automation Testing?
When we are performing automation testing using Selenium Webdriver for some scenarios or elements are not performing as expected. In such cases, we can take the help of Java Script to deal with such situations:
- Sometimes nested elements not accessible in selenium webdriver. For example, if an element present in a tag like a label or div on which selenium webdriver is not able to click in that case, you can use Java Script.
- You can also interact with calendars, Scrolling, Handling Hidden elements, and Drag & drop operations.
How to Execute Java Script Using Selenium?
Execute the Java Script’s selenium Webdriver given an interface “JavascriptExecutor,” which has two methods. That is:
Object executeScript(String arg0, Object arg1); Object executeAsyncScript(String arg0, Object arg1);
By using two methods in our automation script, we can able to execute the Java Script’s. During explaining the Selenium WebDriver hierarchy we have mentioned that RemoteWebDriver which implements the JavascriptExecutor. And all the web browser classes extend the RemoteWebDriver. So by using any browser driver, we can able to execute the Java Script command.
Let us See a Simple Program:
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver","./exefiles/chromedriver.exe"); WebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); JavascriptExecutor js= (JavascriptExecutor)driver; js.executeScript("console.log('Hello.');"); driver.get("https://www.softwaretestingo.com/"); } }
Note: In most of the interview you may face a question regarding the below statement
JavascriptExecutor js= (JavascriptExecutor)driver;
Explanation: Here, we downcast the driver interface to JavascriptExecutor to execute the Java Script because the WebDriver interface has no visibility of JavascriptExecutor interface methods. So to execute the Java scripts command, we have downcast the driver.
We can also the Java scripts without downcast the driver instance if we are:
- Create a Browser class driver: For example, if we are creating an instance of chromedriver class, then, in this case, we don’t need to downcast because chromedriver have extends RemoteWebDriver which have implements JavascriptExecutor methods. So ChromeDriver has indirect access to those methods.
import org.openqa.selenium.chrome.ChromeDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver","./exefiles/chromedriver.exe"); ChromeDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.executeScript("console.log('Hello.');"); driver.get("http://www.softwaretestingo.com/"); } }
- Create a Browser class object and Upcast to RemoteWebDriver
import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver","./exefiles/chromedriver.exe"); RemoteWebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.executeScript("console.log('Hello.');"); driver.get("http://www.softwaretestingo.com/"); } }
executeScript() In details
Syntax: java.lang.Object executeScript(java.lang.String script,java.lang.Object… args)
- Script command which you want to run in form of String. It is mandatory.
- An array of arguments. It is optional. It is the same as we have in the main() method of java program. These arguments will be used in Java Script command.
import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver","./exefiles/chromedriver.exe"); ChromeDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.executeScript("console.log('Hello '+arguments[0] +' Welcome to '+arguments[1]);","User","SoftwareTestingo"); } }
If we saw the method described on the official website, we found that:
Executes JavaScript in the context of the currently selected frame or window. The script fragment provided will be executed as the body of an anonymous function.
That means when we write the below statement:
driver.executeScript(“console.log(‘Hello.’);”);
Then selenium will execute the above Java script like:
function() { console.log("Hello"); }
Return Type of executeScript() method
If the script has a return value (i.e., if the script contains a return statement), then the following steps will be taken:
- For an HTML element, this method returns a WebElement
- For a decimal, a Double is returned
- For a non-decimal number, a Long is returned
- For a boolean, a Boolean is returned
- For all other cases, a String is returned.
- For an array, return a List<Object> with each object following the rules above
- . We support nested lists.
- For a map, return a Map<String, Object> with values following the rules above.
Unless the value is null or there is no return value, in which null is returned, Arguments must be a number, a boolean, a String, WebElement, or a List of any combination of the above. An exception will be thrown if the arguments do not meet these criteria.
Example:
import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "./exefiles/chromedriver.exe"); ChromeDriver driver = new ChromeDriver(); driver.manage().window().maximize(); Object response = driver.executeScript("return 1===2"); System.out.println(response); } }
executeAsyncScript()
Let us understand what’s the difference between Synchronous & Asynchronous. In simple words, Synchronous represents Blocking, and Asynchronous represents Non-blocking.
Let us discuss this in detail. If a program is executed line by line, that’s called synchronous programming. Until the first line execution is completed, the second line will not be executed. But in Asynchronous programming, all the lines start the execution at a time, and it is not blocking any other lines to be executed — every asynchronous piece of code signals when execution is done. The signal is called as a callback.
Example:
- Java is the synchronous programming language
- NodeJS is an Asynchronous programming language
Syntax of executeAsyncScript
java.lang.Object executeAsyncScript(java.lang.String script, java.lang.Object… args)
If you see the official site for the method description:
Execute an asynchronous piece of Java Script in the context of the currently selected frame or window. Unlike executing synchronous Java Script, scripts executed with this method must explicitly signal they are finished by invoking the provided callback. This callback is always injected into the executed function as the last argument.
Lets execute the below Java script command
window.setTimeout(arguments[arguments. length – 1], 5000);
Here, arguments[arguments.length – 1] is a callback function. To get last arguments we need to get the length and minus one. This method calls the function after 5 seconds to execute.
Example:
import java.util.Date; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.chrome.ChromeDriver; public class ExecuteAsynJavascriptCommandsInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "./exefiles/chromedriver.exe"); ChromeDriver driver = new ChromeDriver(); driver.manage().window().maximize(); System.out.println("Start time: " + new Date()); // Down casting driver to JavascriptExecutor JavascriptExecutor js= (JavascriptExecutor)driver; js.executeAsyncScript("window.setTimeout(arguments[arguments.length - 1], 5000);"); System.out.println("End time: " + new Date()); driver.quit(); } }
You can see, execution control was waiting till the java Script function is executed completely and signaled. This happened because we are letting JVM know that we are executing an async piece of code and wait till function callbacks.
Now, what will happen if we execute async code through the executeScript method?
import java.util.Date; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.chrome.ChromeDriver; public class ExecuteAsynJavascriptCommandsInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "./exefiles/chromedriver.exe"); ChromeDriver driver = new ChromeDriver(); driver.manage().window().maximize(); System.out.println("Start time: " + new Date()); // Down casting driver to JavascriptExecutor JavascriptExecutor js= (JavascriptExecutor)driver; js.executeScript("window.setTimeout(arguments[arguments.length - 1], 5000);"); System.out.println("End time: " + new Date()); driver.quit(); } }
This time execution control does not wait because JVM does not know about it. This is the reason to execute an asynchronous piece of code, we need to use executeAsyncScript.
We have discussed various types of locators that are presented in Selenium WebDriver like ID, Name, Classname, TagName, XPath, and CSSSelector. But when we try to locate some elements in an application, those elements are not identifiable because of reasons like element is hidden, an element is deeply nested, or a web application has lots of AJAX calls that time Java Script is helpful to locate the elements.
How to Locate Element Using JavaScript?
In Java Script we have some set of command by using those commands we can easily locate the elements of an web page, those are:
- getElementById
- getElementsByClassName
- getElementsByName
- getElementsByTagName
getElementById Example
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "./exefiles/chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://www.makemytrip.com/"); // Down casting driver to JavascriptExecutor JavascriptExecutor js= (JavascriptExecutor)driver; // Down casting to WebElement because executeScript return a type of Object WebElement element= (WebElement) js.executeScript("return document.getElementById('searchBtn')"); // Getting text String text= element.getText(); System.out.println("Text: "+text); } }
getElementsByClassName Example
import java.util.List; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; public class JavaScriptInSelenium { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "./exefiles/chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://www.makemytrip.com/"); // Down casting driver to JavascriptExecutor JavascriptExecutor js= (JavascriptExecutor)driver; // Down casting to List<WebElement> because executeScript return a type of Object List<WebElement> element= (List<WebElement>) js.executeScript("return document.getElementsByClassName('non-pot')"); // Getting text System.out.println(element.size()); } }
Apart from locating the elemnts of an web page, we can do other operations by using JavaScript.
- Scroll a WebPage
- Taking Screenshot Of the Entire page
- Giving Input to a Text Box
- Handle Hidden Element
- Handle Calendar
Taking Screenshot Of the Entire page
In our other post regarding the Taking Screenshot, we have seen that when we try to capture the screenshot with Selenium WebDriver and TakesScreenshot interface that time, we can able to take the screenshot of the only visible part of the browser, not the full page. So for capturing the full page screenshot, we can take the help of Java Script.
import java.io.File; import org.apache.commons.io.FileUtils; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class CaptureFullWebPage { public static String CaptureScreenShotWithTestStepName(WebDriver driver, String testStepsName) { try{ // down casting WebDriver to use getScreenshotAs method. TakesScreenshot ts= (TakesScreenshot)driver; // capturing screen shot as output type file File screenshotSRC= ts.getScreenshotAs(OutputType.FILE); // Defining path and extension of image String path=System.getProperty("user.dir")+"/ScreenCapturesPNG/"+testStepsName+System.currentTimeMillis()+".png"; // copying file from temp folder to desired location File screenshotDest= new File(path); FileUtils.copyFile(screenshotSRC, screenshotDest); return path; } catch(Exception e) { System.out.println("Some exception occured." + e.getMessage()); return ""; } } public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.chrome.driver", "./exefiles/chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("http://www.softwaretestingo.com/"); // Down casting driver to JavascriptExecutor JavascriptExecutor js = (JavascriptExecutor) driver; // It returns height of view part. You can say it as page height. When you click on page down key // Page scroll by one page. long pageHeight= (long)js.executeScript("return window.innerHeight"); System.out.println("Page height: "+pageHeight); // It is how much you can scroll. It is height if you scroll, you will reach to bottom of page. long scrollableHeight= (long)js.executeScript("return document.body.scrollHeight"); System.out.println("Total scrollable height: "+scrollableHeight); // Finding number of pages. Adding 1 extra to consider decimal part. int numberOfPages=(int) (scrollableHeight/pageHeight)+1; System.out.println("Total pages: "+numberOfPages); // Now scrolling page by page for(int i=0;i<numberOfPages;i++) { CaptureFullWebPage.CaptureScreenShotWithTestStepName(driver, "Page "+(i+1)); js.executeScript("window.scrollBy(0,"+pageHeight+")"); Thread.sleep(2000); } } }
Giving Input to a Text Box
For Sending any input to a text box, we are always using the sendkeys() method, but we can also achieve the same things with Java Script.
When you check the HTML DOm structure of any HTML Element, then you will find an attribute called “Value,” which holds the current value of that element.
For Example, There is a text box for FirstName, and You enter there “SoftwareTestingo,” then the value attributed updated from “Value” to “Value=SoftwareTestingo.”
So when we are not able to enter that value in the text box, that time, we can update the value attribute with the required input so that the same value will be reflected on the text box also.
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 TypeUsingJavascript { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver","./exefiles/chromedriver.exe"); WebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://www.google.com/"); WebElement searchBox= driver.findElement(By.name("q")); // Down casting driver to JavascriptExecutor JavascriptExecutor js = (JavascriptExecutor) driver; // Setting value for "value" attribute js.executeScript("arguments[0].value='selenium'", searchBox); } }
Handle Hidden Element
Sometimes you can say that on a web page, some elements are hidden. In that case, also you can take the help of Javascript. Because by using Java script, we can change the value of an attribute of web element to make it visible and do the required operation.
import java.io.IOException; 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 TypeIntoHiddenElement { public static void main(String[] args) throws IOException { System.setProperty("webdriver.chrome.driver","./exefiles/chromedriver.exe"); WebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.get("file:///C://Users//amodm//Desktop//NewHidden.html"); WebElement searchBox= driver.findElement(By.id("files")); // Down casting driver to JavascriptExecutor JavascriptExecutor js = (JavascriptExecutor) driver; // Setting value for "style" attribute to make input tag visible js.executeScript("arguments[0].style.display='block';", searchBox); searchBox.sendKeys("F:\\Eclipse_WS\\softwaretestingo\\ScreenCapturesPNG\\TypeUsingJS.jpg"); } }
Handle Calendar
We have mentioned with example in how to handle calendar post you can check the post.
Please put an option to remove /or disappear notofications