Most websites have a results page that is usually displayed after the user executes a search on home page.
The results page displays results organized in pages.
Each result has a few different fields and one or more photos.
Any Selenium test that is focused on these results has to work with a collection of result names or prices or any other result attribute.
For example, the following test goes through a list of product names and counts all names that contain a keyword:
public class CollectionTests {
private List<String> titles =
Arrays.asList(
"Sony Alpha a7 II Full-Frame Mirrorless Camera",
"Canon EOS Rebel T7 DSLR Camera",
"DJI Mini 3 Quadcopter Drone Fly More Combo",
"GoPro HERO9 Black Waterproof 5K Sports & Helmet Camera",
"Fujifilm Instax Mini 2-Pack Instant Film",
"Sony Cyber-shot ZV-1 20.1MP 2.9x Digital Camera",
"Samsung PRO Plus+ Adapter 512GB microSDXC Memory Card",
"Kingston Canvas Go! Plus 128GB Memory Card",
"DJI Mini 3 Quadcopter Drone with Remote Control - Grey"
);
private String keyword = "Camera";
@Test
public void getCountOfTitlesContainingKeywordTest() {
int count = 0;
for (String t : titles)
if (t.contains(keyword))
count++;
Assert.assertTrue(count > 0);
}
The test uses a for statement to go through all elements of the titles list. If any of the elements contains the keyword, it increases the value of the counter variable.
This can be done easier using the Java streams as follows:
@Test
public void getCountOfTitlesContainingKeywordTest() {
long count = titles.stream().filter(t -> t.contains(keyword)).count();
Assert.assertTrue(count > 0);
}
The titles list is first converted to a stream, then the stream is filtered so only elements that contain the keyword are included, then the filtered elements of the stream are counted.
Isn’t this nicer than before? Short, concise and clean.
Let’s look into another example.
This time, we have a list of prices that needs to be cleaned up. Each price value starts with the $ sign. The list of prices contains text values. After going through it, we would like to have a list of numbers:
private List<String> prices = Arrays.asList( "$15.23",
"$10.40",
"$76.50",
"$27.30",
"$90.00",
"$61.80",
"$11.20" );
@Test
public void getAllPricesTest() {
List<Double> priceList = new ArrayList<>();
for (String price : prices) {
String cleanedPrice = price.replace("$", "");
Double finalPrice = Double.parseDouble(cleanedPrice);
priceList.add(finalPrice);
}
Assert.assertFalse(priceList.isEmpty());
}
The code goes through each element of the prices list, removes the $ sign from the current element value, converts the new value to double and adds the double value to a new list.
Using streams, the test becomes:
@Test
public void getAllPricesTest() {
List<Double> priceList =
prices.stream()
.map(p -> Double.parseDouble(p.replace("$", "")))
.collect(Collectors.toList());
Assert.assertFalse(priceList.isEmpty());
}
The prices list is converted to a stream, then the code generates a new value for each value of the stream (removes $ from it, converts the remaining value to double), then collects all new values in a new list.
Every time you need to work with collections, streams are the tool that you want to use.