3

I would like to loop through a list of div classes that is dynamically generated in two columns (fixed), rows (dynamically generated). I would like to select a button on the second column with a group of buttons with same name tag.

So far I could not work out how to grab all the row items in a list <Webelement> given the css selector and finding by tagname

The pseudocode I have in mind is:

  • Initialise 2D array for rows and columns
  • Get all items in first column by name
  • Get all items in second column by id
  • while looping through the rows in both columns
  • Locate the item in last row for both columns by name and id
  • When name matches to string "1234"
  • click the button in the second column same row.
  • Assert statement that action has completed successfully
  • Or Assert statement that item could not be found
  • Terminate browser
  • End program

I have this html as a sample to code against:

<div id="bookings">
  <div class="row">
    <div id="25203" class="row">
      <div class="col-md-2">
        <p>Jola</p>
      </div>
      <div class="col-md-2">
        <p>Hunters</p>
      </div>
      <div class="col-md-1">
       <p>105</p>
      </div>
      <div class="col-md-2">
        <p>true</p>
      </div>
      <div class="col-md-2">
        <p>2017-02-25</p>
      </div>
      <div class="col-md-2">
        <p>2017-03-02</p>
      </div>
      <div class="col-md-1">
        <input onclick="deleteBooking(25203)" value="Delete" type="button"/>
      </div>
    </div>
    <div id="25204" class="row"> //I would like to grab items from this list
      <div class="col-md-2">
        <p>Jola</p>
      </div>
      <div class="col-md-2">
        <p>Hunters</p>
      </div>
      <div class="col-md-1">
        <p>105</p>
      </div>
      <div class="col-md-2">
        <p>true</p>
      </div>
      <div class="col-md-2">
        <p>2017-02-25</p>
      </div>
      <div class="col-md-2">
        <p>2017-03-02</p>
      </div>
      <div class="col-md-1">
        <input onclick="deleteBooking(25204)" value="Delete" type="button"/> //I would like to click on this button.
      </div>
    </div>

Any advise on how to use Selenium-webdriver with Java (using Eclipse and Cucumber plugin).

UPDATE: My first attempt to code gives me this:

//Scenario 2: Verify on clicking the delete button for an existing customer
    @Given("^I am on the Hotel booking form with saved customers$")
    public void I_am_on_the_Hotel_booking_form_with_saved_customers() throws Throwable {
    //Validate if customers records exist in the table.     

        List<WebElement> rows = driver.findElements(By.xpath(".//*[@id='bookings']//div[@id]"));
        java.util.Iterator<WebElement> i = rows.iterator();
        while(i.hasNext()) {
            WebElement row = i.next();
            System.out.println(row.getText());              
        }           
    }

    @When("^valid customers data is being displayed$")
    public void valid_customers_data_is_being_displayed() throws Throwable {
        // Write code here that finds and lists all the rows in a table
        WebElement dynamicDivs = driver.findElement(By.xpath(".//*[@id='bookings']"));
        List<WebElement> rows = dynamicDivs.findElements(By.tagName("p"));
        java.util.Iterator<WebElement> i = rows.iterator();
        while(i.hasNext()) {
            WebElement row = i.next();
            System.out.println(row.getText());
        }           
    }

    @When("^I click the delete button$")
    public void i_click_the_delete_button() throws Throwable {
        // Write code to delete a specific customer in a row given the firstname = "Tim" and price = "999.99"
        WebElement pricenumber = driver.findElement(By.className("col-md-1"));
        //List<WebElement> rows1 = classnames.findElements(By.tagName("p"));

        java.util.Iterator<WebElement> i = rows1.iterator();
        while(i.hasNext()) {
            WebElement row1 = i.next();
            System.out.println(row1.getText());
            string firstnames = driver.findElement(By.className("col-md-2"));
            System.out.println(firstnames.getText());

            if (row1.getText() == "999.99" && firstnames == "Tim" )
            {
                driver.findElement(By.className("col-md-1").cssSelector(".col-md-1>input")).click();

            }
            //Assert that row has been deleted.
        }          
    }

    @Then("^I should see the customer details on the last row been deleted$")
    public void i_should_see_the_customer_details_on_the_last_row_been_deleted() throws Throwable {
         // Write code here to search for firstname if it does not exist
        WebElement dynamicDivs = driver.findElement(By.xpath(".//*[@id='bookings']"));
        List<WebElement> rows = dynamicDivs.findElements(By.tagName("p"));
        java.util.Iterator<WebElement> i = rows.iterator();
        while(i.hasNext()) {
            WebElement row = i.next();
            System.out.println(row.getText());
            if (row.getText() != "Tim")
            {
                Assert.assertFalse(row.getText(), "Tim");                   
            }
        }
        driver.close();
        driver.quit();
    }       

Note that the id tag is randomly generated, which means I'll have to loop through and select the last id from the group. eg:

<div id="25217" class="row">
    <div class="col-md-2">
    <p>Tim</p>  
2
  • Not sure now to add a block of html code without rendering post submission of my question. Commented Feb 20, 2017 at 15:17
  • <pre><div id = "bookings"></pre> Commented Feb 20, 2017 at 15:27

1 Answer 1

1

If you put your code in it would help to give more specifics, but try to query it utilizing the

webdriver.findElements(By.XPath("//div[@id='bookings']/div));

which will give you a list of elements which should all be rows. Then for each row you can query them by pulling the ID out of them and then getting another list of elements for the columns like

webdriver.findElements(By.XPath("//div[@id='25204']/div)); 

You can then parse the rows/columns as needed with lists of elements and that will maintain your HTML structure but also allow you to execute like a list. You can assert whatever as you loop through the elements or execute list searching specifics for what you need.

I get that you put another text list of the goals, but it's not 100% clear. If you need more specifics please provide some more coding or pseudo coding structure to indicate your end goal. I hope the elements list helps.

4
  • Here is a sample code I have started to write, its not fully completed. Struggling with getting the List<webelements> to capture the contents that I need. Commented Feb 21, 2017 at 11:21
  • I usually cast to a list type and utilize a searching feature for lists. It cuts down on the time it takes to loop everything for the assertions. The initial discovery of the id's and places will have to loop though. I'm not sure what exactly is "not working" with your code though, what is "contents that you need" in the list? You will likely have to pull the parents and then grab children as it pulls the literal tags out. There is child node navigation as well. So you get a list of divs to determine the id's and then get the list of p's that belong underneath the desired div id.
    – mutt
    Commented Feb 22, 2017 at 0:56
  • With the above code, I've ran as a JUnit runner, the console returned an error for code line - List<WebElement> rows = driver.findElements(By.xpath(".//*[@id='bookings']//div[@id]")); java.lang.NullPointerException at stepDefination.SmokeTests.I_am_on_the_Hotel_booking_form_with_saved_customers(SmokeTests.java:71) Commented Feb 22, 2017 at 18:36
  • you are specifying an explicit @id and not following with an ='something'. If you just want to grab the div you don't need the [@id] part after the //div
    – mutt
    Commented Feb 24, 2017 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.