Search code examples
htmlseleniumxpathtestcomplete

xpath for input based of its label


I want to select an input, based of its label. I found below xpath, which returns 3 inputs, even though two of returned inputs have different labels. I want to understand why it works like that and how to improve it to return correct (one) input element. Here is the xpath:

//input[@id=(//label[.='Max Driving Time_h']/@for)]

And yes, I know I can get the proper input with xpath like this:

//label[.='Max Driving Time_h']/ancestor::div/input

I would just like to understand, what's wrong with the first xpath ;) Thank you in advance!

Here is the HTML code to try...

<!DOCTYPE html>
<html>
   <head>
      <title>Page Title</title>
   </head>
   <body>
      <div class="mat-tab-body-wrapper">
         <mat-tab-body role="tabpanel" class="mat-tab-body ng-tns-c344-232 mat-tab-body-active ng-star-inserted" id="mat-tab-content-4-0" aria-labelledby="mat-tab-label-4-0">
            <div cdkscrollable="" class="mat-tab-body-content ng-tns-c344-232 ng-trigger ng-trigger-translateTab" style="transform: none;">
               <!---->
               <div fxlayout="column" fxlayoutalign="space-between start" style="padding-top: 10px; flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start space-between; align-items: flex-start;" class="ng-star-inserted">
                  <dsg-input-duration class="ng-valid ng-touched ng-dirty">
                     <div flex-wrap="nowrap" style="display: inline-block; margin-right: 15px;" class="ng-valid ng-untouched ng-pristine">
                        <div fxlayout="column" fxlayoutalign="start start" class="mainLayout" style="flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start; align-items: flex-start;">
                           <div class="placeHolder">Max Driving Time</div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <mat-form-field floatlabel="always" class="mat-form-field durationField durationLabel ng-tns-c84-225 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-225">
                                    <div class="mat-form-field-flex ng-tns-c84-225">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-225">
                                          <input matinput="" formcontrolname="hours" id="h" name="h" type="number" min="0" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-225 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false" max="23">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-225">
                                             <label class="mat-form-field-label ng-tns-c84-225 ng-star-inserted" id="mat-form-field-label-179" for="h" aria-owns="h">
                                                <!---->
                                                <mat-label style="visibility: hidden !important;" class="ng-tns-c84-225 ng-star-inserted">Max Driving Time_h</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-225 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-225"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-225">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-225 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-225"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="h" class="durationSpaceForInputs">h</label>
                              <mat-form-field class="mat-form-field durationField durationLabel ng-tns-c84-226 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-has-label ng-valid ng-star-inserted mat-form-field-should-float ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-226">
                                    <div class="mat-form-field-flex ng-tns-c84-226">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-226">
                                          <input matinput="" formcontrolname="minutes" id="m" name="m" type="number" min="0" max="59" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-226 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-226">
                                             <label class="mat-form-field-label ng-tns-c84-226 ng-star-inserted" id="mat-form-field-label-181" for="m" aria-owns="m">
                                                <!---->
                                                <mat-label style="visibility: hidden !important; display: none;" class="ng-tns-c84-226 ng-star-inserted">Max Driving Time_m</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-226 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-226"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-226">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-226 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-226"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="m" class="durationSpaceForInputs">m</label><!----><!---->
                           </div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <div fxlayout="column" class="errorMessage" style="flex-direction: column; box-sizing: border-box; display: flex;">
                                 <!----><!----><!----><!----><!----><!----><!----><!----><!---->
                              </div>
                           </div>
                        </div>
                     </div>
                  </dsg-input-duration>
                  <dsg-input-duration class="ng-valid ng-touched ng-dirty">
                     <div flex-wrap="nowrap" style="display: inline-block; margin-right: 15px;" class="ng-valid ng-untouched ng-pristine">
                        <div fxlayout="column" fxlayoutalign="start start" class="mainLayout" style="flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start; align-items: flex-start;">
                           <div class="placeHolder">Max Elapsed Time</div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <mat-form-field floatlabel="always" class="mat-form-field durationField durationLabel ng-tns-c84-227 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-227">
                                    <div class="mat-form-field-flex ng-tns-c84-227">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-227">
                                          <input matinput="" formcontrolname="hours" id="h" name="h" type="number" min="0" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-227 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false" max="23">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-227">
                                             <label class="mat-form-field-label ng-tns-c84-227 ng-star-inserted" id="mat-form-field-label-183" for="h" aria-owns="h">
                                                <!---->
                                                <mat-label style="visibility: hidden !important;" class="ng-tns-c84-227 ng-star-inserted">Max Elapsed Time_h</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-227 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-227"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-227">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-227 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-227"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="h" class="durationSpaceForInputs">h</label>
                              <mat-form-field class="mat-form-field durationField durationLabel ng-tns-c84-228 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-has-label ng-valid ng-star-inserted mat-form-field-should-float ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-228">
                                    <div class="mat-form-field-flex ng-tns-c84-228">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-228">
                                          <input matinput="" formcontrolname="minutes" id="m" name="m" type="number" min="0" max="59" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-228 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-228">
                                             <label class="mat-form-field-label ng-tns-c84-228 ng-star-inserted" id="mat-form-field-label-185" for="m" aria-owns="m">
                                                <!---->
                                                <mat-label style="visibility: hidden !important; display: none;" class="ng-tns-c84-228 ng-star-inserted">Max Elapsed Time_m</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-228 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-228"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-228">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-228 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-228"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="m" class="durationSpaceForInputs">m</label><!----><!---->
                           </div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <div fxlayout="column" class="errorMessage" style="flex-direction: column; box-sizing: border-box; display: flex;">
                                 <!----><!----><!----><!----><!----><!----><!----><!----><!---->
                              </div>
                           </div>
                        </div>
                     </div>
                  </dsg-input-duration>
                  <dsg-input-duration class="ng-valid ng-touched ng-dirty">
                     <div flex-wrap="nowrap" style="display: inline-block; margin-right: 15px;" class="ng-valid ng-untouched ng-pristine">
                        <div fxlayout="column" fxlayoutalign="start start" class="mainLayout" style="flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start; align-items: flex-start;">
                           <div class="placeHolder">Max Working Time</div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <mat-form-field floatlabel="always" class="mat-form-field durationField durationLabel ng-tns-c84-229 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-229">
                                    <div class="mat-form-field-flex ng-tns-c84-229">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-229">
                                          <input matinput="" formcontrolname="hours" id="h" name="h" type="number" min="0" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-229 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false" max="23">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-229">
                                             <label class="mat-form-field-label ng-tns-c84-229 ng-star-inserted" id="mat-form-field-label-187" for="h" aria-owns="h">
                                                <!---->
                                                <mat-label style="visibility: hidden !important;" class="ng-tns-c84-229 ng-star-inserted">Max Working Time_h</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-229 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-229"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-229">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-229 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-229"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="h" class="durationSpaceForInputs">h</label>
                              <mat-form-field class="mat-form-field durationField durationLabel ng-tns-c84-230 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-has-label ng-valid ng-star-inserted mat-form-field-should-float ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-230">
                                    <div class="mat-form-field-flex ng-tns-c84-230">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-230">
                                          <input matinput="" formcontrolname="minutes" id="m" name="m" type="number" min="0" max="59" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-230 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-230">
                                             <label class="mat-form-field-label ng-tns-c84-230 ng-star-inserted" id="mat-form-field-label-189" for="m" aria-owns="m">
                                                <!---->
                                                <mat-label style="visibility: hidden !important; display: none;" class="ng-tns-c84-230 ng-star-inserted">Max Working Time_m</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-230 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-230"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-230">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-230 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-230"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="m" class="durationSpaceForInputs">m</label><!----><!---->
                           </div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <div fxlayout="column" class="errorMessage" style="flex-direction: column; box-sizing: border-box; display: flex;">
                                 <!----><!----><!----><!----><!----><!----><!----><!----><!---->
                              </div>
                           </div>
                        </div>
                     </div>
                  </dsg-input-duration>
                  <dsg-input-number controlname="maxDistance">
                     <div class="ng-touched ng-dirty ng-valid" style="display: inline-block;">
                        <mat-form-field floatlabel="always" class="mat-form-field ng-tns-c84-231 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-touched ng-pristine">
                           <div class="mat-form-field-wrapper ng-tns-c84-231">
                              <div class="mat-form-field-flex ng-tns-c84-231">
                                 <!----><!---->
                                 <div class="mat-form-field-infix ng-tns-c84-231">
                                    <input matinput="" type="number" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-231 ng-valid cdk-text-field-autofill-monitored ng-touched ng-pristine" autofocus="" autocomplete="off" step="" id="maxDistance" data-placeholder="" aria-invalid="false" aria-required="false" min="-Infinity" max="2147483647" maxlength="14">
                                    <span class="mat-form-field-label-wrapper ng-tns-c84-231">
                                       <label class="mat-form-field-label ng-tns-c84-231 ng-star-inserted" id="mat-form-field-label-191" for="maxDistance" aria-owns="maxDistance">
                                          <!---->
                                          <mat-label class="ng-tns-c84-231 ng-star-inserted">Max Distance [km]</mat-label>
                                          <!----><!---->
                                       </label>
                                       <!---->
                                    </span>
                                 </div>
                                 <!---->
                              </div>
                              <div class="mat-form-field-underline ng-tns-c84-231 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-231"></span></div>
                              <!---->
                              <div class="mat-form-field-subscript-wrapper ng-tns-c84-231">
                                 <!---->
                                 <div class="mat-form-field-hint-wrapper ng-tns-c84-231 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                    <!---->
                                    <div class="mat-form-field-hint-spacer ng-tns-c84-231"></div>
                                 </div>
                                 <!---->
                              </div>
                           </div>
                        </mat-form-field>
                     </div>
                  </dsg-input-number>
               </div>
               <!---->
            </div>
         </mat-tab-body>
         <mat-tab-body role="tabpanel" class="mat-tab-body ng-tns-c344-233 ng-star-inserted" id="mat-tab-content-4-1" aria-labelledby="mat-tab-label-4-1">
            <div cdkscrollable="" class="mat-tab-body-content ng-tns-c344-233 ng-trigger ng-trigger-translateTab" style="transform: translate3d(100%, 0px, 0px); min-height: 1px;">
               <!---->
            </div>
         </mat-tab-body>
         <!---->
      </div>
   </body>
</html>

Solution

  • Try below XPath:

    //input[@id=(./following::label[.='Max Driving Time_h']/@for)]
    

    Your XPath doesn't work because it states that you need to find all input nodes if they have the same @id value as the @for value of label with text 'Max Driving Time_h' while you need only the input with corresponding label (note the . that means "context node")