1

I have a search result page which contains many product items which are produced as a search result. I can get the list of the product items. But there are product details like price, discount, shipping price which are inside these webelements as child elements. How can I use page object factory model to get the values of these child elements automatically by using the @FindBy annotation.

At the moment I do not know how so I am getting them explicitly by providing the context of the parent WebElement in the findElement(By) function explicitly rather than the automatic mechanism of POF. Question is how to make the context as a WebElement rather than a driver object for a PageObject class. I have not been able to find any understandable web article explaining how to do it. Could someone explain a SIMPLE way to do it hopefully with an example.... I would be really grateful. Below is the code to explain the Test Class and the class to represent the product.

public class TestProducts {

.....
 //I can get the list of products from a 
 List<WebElement> we_prod_box_list = driver.findElements(By.xpath("//div[@id='content']/descendant::div[starts-with(@class,'product_box_container')]"));
.....
}

public class ProductItem {

private WebDriver driver = null;
private Actions action = null;
private WebElement we_prod_box = null;

public String we_prod_box_title = "";
public WebElement we_pt = null;
public String slideImgTitle = "";
public String oldPrice = "";
public String oldPriceTitle = "";
public String subPrice = "";
public WebElement we_purch_disc = null;
private WebDriverWait wait = null;
public String shippingText = "";
public String shippingCost = "";
public String discPrice = "";
    .....

    we_pt = we_prod_box.findElement(By.xpath(".//div[contains(@class, 'subcategor_price_tag')]"));
slideImgTitle = we_pt.findElement(By.xpath(".//div[contains(@class, 'subcategor_slideimgtitle')]")).getText();
oldPrice = we_prod_box.findElement(By.xpath(".//div[contains(@class, 'oldprice')]")).getText();
oldPriceTitle = we_prod_box.findElement(By.xpath(".//div[contains(@class, 'oldprice')]")).getAttribute("title");
subPrice = we_prod_box.findElement(By.xpath(".//span[contains(@class, 'sub-price')]")).getText();
     ......
}
win
  • 119
  • 2
  • 14

3 Answers3

0

You can get the 4 webelements which contains the attribute of the product item into 4 different lists by using @FindBy. Just pass the complete xpath of these elements to FindBy. You can iterate the lists to get individual values to test or create a Product Item object etc etc...

Grasshopper
  • 8,908
  • 2
  • 17
  • 32
  • Thanks for your suggestion. The problem which I was facing, was that I could not uniquely identify a on the fly generated search result product items. So how could I uniquely identify a child webelement of the search result product items? So I was looking for something else which could automatically set the values of the child elements also using the POF @FindBy annotation. I found the answer in http://stackoverflow.com/questions/24251739/selenium-webdriver-page-factory-initialization-using-paths-relative-to-other-el?rq=1 – win Aug 19 '16 at 02:04
0

You would want to have a "factory" method in TestProducts to generate ProductItem instances:

TestProducts.getProductItems() {
    List<ProductItem> items = new ArrayList<ProductItem>();
    List<WebElement> we_prod_box_list = driver.findElements(By.xpath("//div[@id='content']/descendant::div[starts-with(@class,'product_box_container')]"));
    for (WebElement item : we_prod_box_list) {
        ProductItem newItem = new ProductItem(driver, item.getUniqueIdOfItemContainer);
        items.add(newItem);

Of course, this implies that ProductItem has a constructor that takes an argument that represents a unique id for that item...I often see an attribute on the div wrapper around items. The constructor then sets the id, e.g. itemWrapperId, for use by other methods.

The ProductItem methods then use findElements to get item information based from that root. E.g. for subPrice in ProductItem

private itemWrapperLocator = "//div[@id='content']/descendant::div[@class,'product_box_container" + itemWrapperId + "')]";

public String subPriceLocator = ".//span[contains(@class, 'sub-price')]";
public getSubPrice() {
    this.driver.findElement(By.xpath(this.itemWrapperLocator)).findElement(By.xpath(subPriceLocator)).getText();

Note that I just typed this into here, so please excuse syntax errors...there should be enough here that you get the drift.

Breaks Software
  • 1,721
  • 1
  • 10
  • 15
  • Thanks for your suggestion. The problem which I was facing, was that I could not uniquely identify a on the fly generated search result product items. So how could I uniquely identify a child webelement of the search result product items? So I was looking for something else which could automatically set the values of the child elements also using the POF @FindBy annotation. I found the answer in http://stackoverflow.com/questions/24251739/selenium-webdriver-page-factory-initialization-using-paths-relative-to-other-el?rq=1 – win Aug 19 '16 at 02:07
0

This is the real solution that worked for me and what I was looking for. Selenium Webdriver: Page factory initialization using paths relative to other elements?

Community
  • 1
  • 1
win
  • 119
  • 2
  • 14