Geb: Web element locator for multi element navigator

Viewed 446

I have a html page with an element called Student and it has multiple rows like below:

Student: Foo Bar
         Class X
         Section A

I was able to locate the Student element using XPath like this: //b[contains(text(),'Student')] but I want to extract the same thing using jquery selector and extract it's child elements like Foo Bar, Class X and Section A using jquery Selector

I tried something like below but it didn't work: student(wait: true) { $('b', text: contains('Student:')).parent().parent()

Here is how the html looks:

<tr>
   <td colspan="2" align="left" height="25" class="SubSectionTitle" style=""><b style="">&nbsp;Student Information</b></td>
</tr>
<tr>
   <td valign="top" class="Label" rowspan="3"><b style="">Student:</b></td>
   <td style="">Foo Bar</td>
</tr>
<tr>
   <td>Class X</td>
</tr>
<tr>
   <td>Section A</td>
</tr>
1 Answers

Because your question is unclear, I am showing you several options:

HTML page src/test/resources/page-q66129162.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <body>
    <table>
      <tr>
        <td colspan="2" align="left" height="25" class="SubSectionTitle" style=""><b style="">&nbsp;Student Information</b>
        </td>
      </tr>
      <tr>
        <td valign="top" class="Label" rowspan="3"><b style="">Student:</b></td>
        <td style="">Foo Bar</td>
      </tr>
      <tr>
        <td>Class X</td>
      </tr>
      <tr>
        <td>Section A</td>
      </tr>
    </table>
  </body>
</html>

Geb test:

package de.scrum_master.stackoverflow.q66129162

import geb.spock.GebSpec
import org.openqa.selenium.By

class MultiElementNavigatorIT extends GebSpec {
  static url = this.getResource("/page-q66129162.html").toString()

  def test() {
    given:
    go url

    when:
    def xp = $(By.xpath("//b[contains(text(),'Student:')][1]"))

    then:
    xp.text() == "Student:"
    xp.parent().text() == "Student:"
    xp.parent().parent().text() == "Student: Foo Bar"
    xp.parent().parent().parent().text() == " Student Information\nStudent: Foo Bar\nClass X\nSection A"

    when:
    def nav = $('b', text: contains('Student:'))

    then:
    nav.text() == "Student:"
    nav.parent().text() == "Student:"
    nav.parent().parent().text() == "Student: Foo Bar"
    nav.parent().parent().parent().text() == " Student Information\nStudent: Foo Bar\nClass X\nSection A"
  }
}

Or if you like it a bit more compact:

package de.scrum_master.stackoverflow.q66129162

import geb.spock.GebSpec
import org.openqa.selenium.By
import spock.lang.Unroll

class MultiElementNavigatorIT extends GebSpec {
  static url = this.getResource("/page-q66129162.html").toString()

  @Unroll
  def "select by #selectorType"() {
    given:
    go url
    def selector = selectorClosure()

    expect:
    selector.text() == "Student:"
    selector.parent().text() == "Student:"
    selector.parent().parent().text() == "Student: Foo Bar"
    selector.parent().parent().parent().text() == " Student Information\nStudent: Foo Bar\nClass X\nSection A"

    where:
    selectorType | selectorClosure
    "XPath"      | { $(By.xpath("//b[contains(text(),'Student:')][1]")) }
    "CSS"        | { $('b', text: contains('Student:')) }
  }
}

If your question was rather how to select from a multi element navigator, you can use something like myNavigator.first() or myNavigator[0].

Related