0

I am creating a function called GetTextboxLabel which does exactly what it says, gets the label of the given IWebElement declared in my POM framework.

Instead of declaring every textbox label in the page object classes, I would rather just be able to call something like the following:

Textbox.GetTextboxLabel()

And then use that in assertions, like this:

Assert.That("Username:" == Username.GetTextboxLabel());

In my application each label field is directly above the textbox field, so it is safe to assume that the first html element with the type of label above the textbox (input) html element in the DOM is the textboxes label. You can see here that I have an input with "id='CUSIP'" and above it, there is a label with the text of 'CUSIP'. The function would return the label text.

<div class="form-group">
    <label class="control-label col-md-3">CUSIP</label>
    <div class="col-md-9">
        <input class="form-control" data-val="true" data-val-length="CUSIP must be exactly 9 characters long" data-val-length-max="9" data-val-length-min="9" data-val-required="The Cusip field is required." id="Cusip" name="Cusip" type="text" value="">
        <span class="field-validation-valid" data-valmsg-for="Cusip" data-valmsg-replace="true"></span>
    </div>
</div>

Could anyone offer some assistance? Is there any way to do this with XPath? Any advice would be appreciated.

EDIT: I am seeking the PREVIOUS label field, not the next.

JeffC
  • 22,180
  • 5
  • 32
  • 55
JOberloh
  • 1,026
  • 2
  • 11
  • 20
  • Possible duplicate of [Find next sibling of any given element with Selenium WebDriver](https://stackoverflow.com/questions/41706759/find-next-sibling-of-any-given-element-with-selenium-webdriver) – mrfreester Oct 09 '17 at 14:59
  • I am looking for the previous, not the next. Also, not the immediate sibling, the previous record with a specific html tag. – JOberloh Oct 09 '17 at 15:24
  • 2
    Feel free to combine that answer, which tells you how to get elements relative to your current element which seems to be the most generally unique part of this question, with all the other answers that will tell you how to use xpath axes to get ancestors, preceding, etc. I might post a comment to help you tailor your xpath if I get a moment, but there are answers out there to get you in the right direction. – mrfreester Oct 09 '17 at 15:28

2 Answers2

1

There are a few ways to do this... here are a couple examples. Assume e is the INPUT tag that you pass in or use an extension method on.

This one uses a relative XPATH (starts with .), goes up two levels (..), then down to the LABEL.

e.FindElement(By.XPath("./../../label")).Text;

This one also uses a relative XPATH (starts with .) and assumes that the desired LABEL is the first ancestor.

e.FindElement(By.XPath("./ancestor::label")).Text;
JeffC
  • 22,180
  • 5
  • 32
  • 55
0

As JeffC pointed out, my previous answer doesn't work if there are more than one element. So I copied your example 4 times and changed the ID's for each of the input elements.

<div class="form-group">
    <label class="control-label col-md-3">CUSIP</label>
    <div class="col-md-9">
        <input class="form-control" data-val="true" data-val-length="CUSIP must be exactly 9 characters long" data-val-length-max="9" data-val-length-min="9" data-val-required="The Cusip field is required." id="Cusip1" name="Cusip" type="text" value="">
        <span class="field-validation-valid" data-valmsg-for="Cusip" data-valmsg-replace="true"></span>
    </div>
</div>

<div class="form-group">
    <label class="control-label col-md-3">CUSIP</label>
    <div class="col-md-9">
        <input class="form-control" data-val="true" data-val-length="CUSIP must be exactly 9 characters long" data-val-length-max="9" data-val-length-min="9" data-val-required="The Cusip field is required." id="Cusip2" name="Cusip" type="text" value="">
        <span class="field-validation-valid" data-valmsg-for="Cusip" data-valmsg-replace="true"></span>
    </div>
</div>

<div class="form-group">
    <label class="control-label col-md-3">CUSIP</label>
    <div class="col-md-9">
        <input class="form-control" data-val="true" data-val-length="CUSIP must be exactly 9 characters long" data-val-length-max="9" data-val-length-min="9" data-val-required="The Cusip field is required." id="Cusip3" name="Cusip" type="text" value="">
        <span class="field-validation-valid" data-valmsg-for="Cusip" data-valmsg-replace="true"></span>
    </div>
</div>

<div class="form-group">
    <label class="control-label col-md-3">CUSIP</label>
    <div class="col-md-9">
        <input class="form-control" data-val="true" data-val-length="CUSIP must be exactly 9 characters long" data-val-length-max="9" data-val-length-min="9" data-val-required="The Cusip field is required." id="Cusip4" name="Cusip" type="text" value="">
        <span class="field-validation-valid" data-valmsg-for="Cusip" data-valmsg-replace="true"></span>
    </div>
</div>

I then used this XPATH below to find EACH label above the input just fine as long as I traded out the "ID" for the appropriate input ID per the example given.

//div[div[input[contains(@id, 'Cusip1')]]]//label

//div[div[input[contains(@id, 'Cusip2')]]]//label

//div[div[input[contains(@id, 'Cusip3')]]]//label

//div[div[input[contains(@id, 'Cusip4')]]]//label

Hope it all goes well. Peace!

IamBatman
  • 975
  • 12
  • 18
  • This won't work because OP is using an extension method off of a found web element (`Textbox`). – JeffC Oct 09 '17 at 17:41
  • Also, the `/preceding::label` XPath is not correct. It will not return the immediately preceding `LABEL`, it will return the one preceding it. `preceding` excludes ancestors, which is the OP wants. – JeffC Oct 09 '17 at 17:44
  • Fine, I'll update my answer. Geeze, it worked fine for me, but I only tested it with the example given. I just created 4 instances of the example and got my next answer to find each instance fine. – IamBatman Oct 09 '17 at 17:51
  • It's weird... when I used xpathtester.com/xpath it finds the ancestor but when I use `$x()` in Chrome it doesn't find it. When I read [this guide](https://developer.mozilla.org/en-US/docs/Web/XPath/Axes) it states, `preceding - Indicates all the nodes that precede the context node in the document except any **ancestor**, attribute and namespace nodes.` So ancestor nodes should not be included, which the LABEL is an ancestor. – JeffC Oct 09 '17 at 19:15