Showing posts with label selenium. Show all posts
Showing posts with label selenium. Show all posts

Monday, December 12, 2022

Selenium - Configure TestNG to your Selenium framework.

To enable TestNG features in out test framework, as the first step we need to load the TestNG libraries to our test development environment(Eclipse).
  • Go to mvnreposotory.com and type in "testng"in the search bar. 
  • In the search results, select the latest available for dependency version. At the time of writing this blog I got below 7.6.1 version. 
  • Copy maven syntax for the dependency, so that we can paste it to our pom.xml. 
  • Once copied append it to the pom.xml of your maven project (which the framework was being built.
  • Accordingly I added below to my pom.xml.
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.6.1</version>
    <scope>test</scope>
</dependency>

Also we need to install the testNG plugin to the IDE. Go to Help >> Eclipse Market Place >> search for "TestNG"
Select to install the plugin and you are good.

Saturday, November 12, 2022

Selenium - Explicit wait

 This post is not about explicit wait concept in Selenium. But about how we could convert standard explicit wait command to an action method.

So our standard command set is like this:

	WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(5));
	wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector(".mb-3")));

Lets make the action class;

public void waitExplicity(By findBy) {
	WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
	wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(findBy));																									
}

This is a reusable method and therefore we should maintain it within the Abstract Components of our test framework.

(btw, hope you noticed the By locator being sent into wait.until as a parameter. The child class which will be extending the AbstractComponent class should set the value for this.)

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 :)



Friday, November 4, 2022

Selenium - Composite Actions

Amazing piece that I learnt today; Composite actions. Its a concept in which you carry several action commands within one line of Selenium code.

For an example, un the below syntax I perform these actions;

move to the search bar, press it, hold down shift key and enter a text and then double-clicking on the text.

So how is it done. 

We have used the "Actions" class within org.openqa.selenium.interactions.Actions.

Actions a = new Actions(driver);
WebElement caps = driver.findElement(By.xpath("//input[@id=\"twotabsearchtextbox\"]"));
a.moveToElement(caps).clickAndHold().keyDown(Keys.SHIFT).sendKeys("iphoneX").doubleClick().build().perform()

It supports many actions such as below 

clickAndHold().

keyDown(Keys).

sendKeys("iphoneX")

doubleClick()

Once you have selected the action classes required for your test, in Selenium Java you need to end the command with .build().perform(); 

Complete code is as below;

Selenium - Xpath Locators

1. By Tagname
 //tagname[@attribute='value'] 
driver.findElement(By.xpath("//input[@placeholder='Name']")) 

2. By index of the attribute 
 //tagname[@attribute='value'][index] 
 driver.findElement(By.xpath("//input[@type='text'][2]")) 
Used when your attribute and the value are same for multiple elements 

3. By tagnames when there are many instances of the childtag. 
 //parenttag/childtag[index]) 
driver.findElement(By.xpath("//form/input[3]")) 
Use index when there are many instances of child tag and you have to locate one of them.) 

 4. By parent to child-tag 
//parenttag[@attribute='value']/childtag[index]) 
driver.findElement(By.xpath(" //div[@class='forgot-pwd-btn-conainer']/button[1]")) 

 5. With regular expression 
 //tagname[contains(@class,'value')] driver.findElement(By.xpath("//button[contains(@class,'submit')]"))

Tuesday, February 2, 2010

Cloud and open source meet to test Web apps

Start-up Sauce Labs receives funding to support open-source Selenium project on-premise and in the cloud.

Blog post by Dave Rosenberg on Software, Interrupted.
http://news.cnet.com/8301-13846_3-10437699-62.html

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