Java Streams and Lambdas in Selenium WebDriver

Overview: Java Streams and Lambdas

Lambdas

A lambda expression is a microcode that takes in parameter(s) and returns a value. Lambda expressions are similar to the methods, but they are anonymous and they can be implemented right in the body of a method.

Lambdas Syntax

parameter -> expression //to use single parameter & expression
(parameter1, parameter2) -> expression //to use multiple parameters & expression
(parameter1, parameter2) -> {code block} //to use multiple parameters & conditions, loops and more complex logic

Streams

A stream of objects supports both sequential and parallel aggregate operations. Examples include finding the max or min element and finding the first element matching the giving criteria in a declarative way similar to SQL statements used in SELECT queries.

Streams Syntax

List<String> myList =
    Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);

Implementation of Java Streams and Lambdas in Selenium WebDriver

Java Lambdas and Streams simplify the Selenium WebDriver code, especially when you are working with web tables, handling windows/frames, sorting the list of web elements, or filtering the web elements from the collection.

Steps for Implementation

Step 1:

Create a Maven Java project to get started with the implementation of Java Streams and Lambdas in Selenium WebDriver. Search for dependencies such as Selenium Java, WebDriver Manager, and TestNG from the Maven repository location https://mvnrepository.com/ and add to pom.xml as shown below.

Searching for dependencies

Step 2:

Create a TestNG class and add the below test methods.

Scenario 1:

The below test method will find out the list of all the hyperlinks from the demowebshop page and then filter out the links which are having only Linktext.

	@Test(description = "Test to filter links from the web page")
	public void tc1_filter_links() {
		WebDriverManager.chromedriver().setup();
		WebDriver driver=new ChromeDriver();

		driver.get("http://demowebshop.tricentis.com");
		List<WebElement> links=driver.findElements(By.tagName("a"));
		System.out.println("No of Links :"+links.size());
		//Below Code is using Lambdas & Streams
		List<String> filterlinks=links.stream().filter(ele->!ele.getText().equals("")).map(ele->ele.getText()).collect(Collectors.toList());
		System.out.println("After Applying Filter, Links having only Linktext :"+filterlinks.size());
		filterlinks.forEach(System.out::println);
		driver.close();
	}

Expected Output on Console:

  • No of Links: 95
  • After Applying Filter, Links having only Linktext: 66

Scenario 2:

The below test method will filter the products by prices from the list of having greater than $1000 from the home page of the demowebshop.

prodPrices=driver.findElements(By.xpath(“//div[@class=”prices”]”)); Map products_map=new HashMap(); for(int i=0;i 1000 using filter & lambda ****”); System.out.println(“**** Below Products price is > 1000 ****”); products_map.entrySet().stream().filter( e – > e.getValue() > 1000).forEach(v->System.out.println(v)); driver.close(); }” data-lang=”text/x-java”>

	@Test(description ="Test to filter the products which are >1000")
	public void tc2_filter_price()
	{
		WebDriverManager.chromedriver().setup();
		WebDriver driver=new ChromeDriver();
		driver.get("http://demowebshop.tricentis.com/");


		List<WebElement> prodTitles=driver.findElements(By.xpath("//h2[@class="product-title"]"));
		List<WebElement> prodPrices=driver.findElements(By.xpath("//div[@class="prices"]"));

		Map <String,Double>products_map=new HashMap<String,Double>();
		
		for(int i=0;i<prodTitles.size();i++) 
		{
			String title=prodTitles.get(i).getText();
			double price=Double.parseDouble(prodPrices.get(i).getText());

			products_map.put(title, price);

		}
		//Below Code is using Lambdas & Streams	
		//find product whose price is greater than 1000 (Process using filter)
		System.out.println("**** Product price is > 1000 using filter & lambda ****");
		System.out.println("**** Below Products price is > 1000                ****");
                products_map.entrySet().stream().filter( e -> e.getValue() > 1000).forEach(v->System.out.println(v));
		driver.close();
    }

Expected Output on Console:

  • Product price is > 1000 using filter & lambda
  • Below Products price is > 1000
  • Build your own expensive computer=1800.0
  • Build your own computer=1200.0
  • 14.1-inch Laptop=1590.0

Scenario 3:

The below test method will make the product list sorted by AZ.

product_items=driver.findElements(By.xpath(“//h2[@class=”product-title”]”)); List beforesort=product_items.stream().map(item->item.getText()).collect(Collectors.toList()); System.out.println(“Before Sort : ” +beforesort); List aftersort=product_items.stream().map(item->item.getText()).sorted().collect(Collectors.toList()); System.out.println(“After Sort : “+aftersort); driver.close(); }” data-lang=”text/x-java”>

	@Test(description = "Test to make the products in Sorted Order A-Z")
	public void tc3_sorted_list()
	{
		WebDriverManager.chromedriver().setup();
		WebDriver driver = new ChromeDriver();

		driver.get("http://demowebshop.tricentis.com/");
		driver.findElement(By.xpath("//ul[@class="top-menu"]//a[normalize-space()='Books']")).click();

		Select sortbydrp=new Select(driver.findElement(By.id("products-orderby")));
		sortbydrp.selectByVisibleText("Name: Z to A");
		
		List<WebElement> product_items=driver.findElements(By.xpath("//h2[@class="product-title"]"));
		List<String> beforesort=product_items.stream().map(item->item.getText()).collect(Collectors.toList());
		System.out.println("Before Sort : " +beforesort);
		List<String> aftersort=product_items.stream().map(item->item.getText()).sorted().collect(Collectors.toList());
		System.out.println("After Sort : "+aftersort);
		driver.close();
	}

Expected Output on Console:

  • Before sort: [Science, Health Book, Fiction EX, Fiction, Copy of Computing and Internet EX, Computing and Internet]
  • After sort: [Computing and Internet, Copy of Computing and Internet EX, Fiction, Fiction EX, Health Book, Science]

Scenario 4:

The below test method will handle switching to Windows.

@Test(description = "Test to Handle Windows")
	public void tc4_handle_windows()
	{
		WebDriverManager.chromedriver().setup();
		WebDriver driver = new ChromeDriver();
		driver.get("https://demoqa.com/browser-windows");
		driver.findElement(By.id("tabButton")).click();
		
		Set<String>windowIds=driver.getWindowHandles(); // Here using Set collection
		//Print the url's using lambda expression
		windowIds.forEach(winid -> System.out.println(driver.switchTo().window(winid).getCurrentUrl()));
		driver.close();
    }

Expected Output on Console:

  • https://demoqa.com/browser-windows
  • https://demoqa.com/sample

Conclusion

The above is a glimpse of the applications of Java Lambdas and Streams in Selenium to simplify the WebDriver code. The above test methods are some of the common scenarios used in the automation of web applications using Selenium WebDriver API, but not limited to these. Java Lambdas and Streams can be used in any kind of scenario on web tables, handling windows/frames, sorting the list of web elements, or filtering the web elements from a collection.

.

Leave a Comment