Showing posts with label Page Object Model. Show all posts
Showing posts with label Page Object Model. Show all posts

Saturday, November 12, 2022

Selenium - POM and Action Methods - 2

 Lets check how the below segment can be changed to page object model.

1
2
3
4
5
6
List<WebElement> products = driver.findElements(By.cssSelector(".mb-3"));	

WebElement prod =products.stream().filter(product->
product.findElement(By.cssSelector("b")).getText().equals(productName)).findFirst().orElse(null);

prod.findElement(By.xpath("//div[@class='card-body']/button[2]")).click();

Lets take the web element descriptions first; Here we are locating a products list (findElements by the classname csslocator). Since its a list we make it of the type List<WebElement> (line 1). This is how it is done by using @FindBy (we discussed in part 1)

@FindBy(css = ".mb-3")
List<WebElement> products;

Afterwards we can do an action class to findElements. I have called a wait method from the abstract components. You can ignore that for the moment. -- let's not distract ourselves with that in this post peepsies ..

public List<WebElement> getProductList(){
	waitExplicity(productBy);
	return products;
}

Next (line 3-4) we go through the list and filter the product which matches the product name that we specify through a String. This is how it is converted to an action method.

public WebElement getProductByName(String productName){
	WebElement prod =getProductList().stream().filter(product->
	product.findElement(By.cssSelector("b")).getText().equals(productName)).findFirst().orElse(null);
	return prod;
}

Let me add bit of details here; If you look at the line 3 of our first code snippet, the stream filter results are assigned to a variable called prod. How is the prod extracted? By traversing though the products, which is the list of products. With me? ook one step ahead-

How do we get the products from our POM & Action Methos approach? via the getProductList action method. 

So that's what we have done above. We have getProductList().stream().filter .... instead previous products.stream().filter ....

Now next is the fun part! See what we do when we do addToCart.

public void addToCart(String productName){
		WebElement chosenProduct = getProductByName(productName);
		chosenProduct.findElement(addtoCartBtn).click();
}

We use getProductByName(productName) and assign the returning WebElement to 'chosenProduct' variable.  same concept as above. The list web element is replaced by the action method that we created to get the list webelement.

In the next line we do a findElement from within the chosenProduct context, not driver context (noticed!) This is not POM struff. Its about how Selenium facilitate different locator contexts.

However, we cannot use the elements defined in POM to other context. Only driver context could use them. So we have to use the long By.locator methods or we could defined them separately and use here. See.. notice the line 1 below.

By addtoCartBtn = By.xpath("//div[@class='card-body']/button[2]");

public void addToCart(String productName){
	WebElement chosenProduct = getProductByName(productName);
	chosenProduct.findElement(addtoCartBtn).click(); //You cannot use Page objects when you are using a WebElement context
}

So that's about what I learnt on this.. See below for the connected code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        @FindBy(css = ".mb-3")
	List<WebElement> products;

	//WebElements defined under By type to be used in WebElement context. 
	//You can use POs only in driver context
	By productBy = By.cssSelector(".mb-3");
	By addtoCartBtn = By.xpath("//div[@class='card-body']/button[2]");
	
	public List<WebElement> getProductList(){
		waitExplicity(productBy);
		return products;
	}
	
	public WebElement getProductByName(String productName){
		WebElement prod =getProductList().stream().filter(product->
		product.findElement(By.cssSelector("b")).getText().equals(productName)).findFirst().orElse(null);
		return prod;
	}
	
	public void addToCart(String productName){
		WebElement chosenProduct = getProductByName(productName);
		chosenProduct.findElement(addtoCartBtn).click();
	}





Selenium - Page Object Model and Action Methods

 

How we change this code to PageObjectModel and action classes.

1
2
3
driver.findElement(By.id("userEmail")).sendKeys("testA1@gmail.com");
driver.findElement(By.id("userPassword")).sendKeys("testA1#");
driver.findElement(By.id("login")).click();

Page Objects

We can convert the locators  to Page Objects this way

/*	Page Objects Model*/
	@FindBy(id="userEmail")
	WebElement useremail;
		
	@FindBy(id="userPassword")
	WebElement userpass;
		
	@FindBy (id="login")
	WebElement login;

How do we do it

1- Use @FindBy from org.openqa.selenium.By in Selenium. Consider this is replacing "driver.findElement(By" in our standard way of locating elements. 

2- Next put the locator type; id, css, xpath, classname etc

3- Add the relative value next to the locator type. For an example, if you choose 'id' as the locator type, you should get the 'id' of the element. In my case the id of the element that I chose is 'userEmail'. So I build my line like this; @FindBy(id="userEmail")

4- That's not all; We need to let Selenium know what the web element is. So add this.

WebElement <element>. In my case WebElement username;

5- So it makes up our page objects this way;

@FindBy(id="userEmail")

WebElement userName;


Action Classes

As action we input username, pass and press login button. I will show you how these can be segmented out to an action class;

public void Login(String email, String pass){
	useremail.sendKeys(email);
	userpass.sendKeys(pass);
	login.click();
}

I think you can easily see how we have used each of the above page objects to action.

eeasy ha !! wait for more cool stuffs peeps :)



Featured

Selenium - Page Object Model and Action Methods

  How we change this code to PageObjectModel and action classes. 1 2 3 driver . findElement ( By . id ( "userEmail" )). sendKeys (...

Popular Posts