How can I view the xpath of a selected element?

How can I view the xpath of a selected element?

I'm checking for a user on a web interface and clicking an edit button in the corresponding table, but the button and table itself are identical and therefore not uniquely identifiable. I can find the text in the table, so my approach was to grab the xpath where that's found, and derive the button's xpath from that. The xpath itself will be variable based on how/what users are on the page so I can't use anything absolute.

I can find the text element using this, but I don't know of a way to use that to derive the corresponding button. Feel free to point me towards a different solution for the problem.

userLookupElement = driver.find_element(By.XPATH,"//*[contains(text(), 'SeleniumTest')]")

e.g.

xpath holding text (found using browser ext) /html/body/main/div[2]/div/div/div/div[2]/div/div[2]/div/div/form/div[5]/table/tbody/tr[18]/td[1]

corresponding button /html/body/main/div[2]/div/div/div/div[2]/div/div[2]/div/div/form/div[5]/table/tbody/tr[18]/td[3]/label

Edit: Included HTML. Attempting to select based on username "SeleniumTest" and find the corresponding "Edit User" button element.

<tr ng-repeat="user in userData track by $index" ng-class-odd="'o-table-bkodd'" ng-class-even="'o-table-bkeven'" class="ng-scope o-table-bkeven">
                <td colspan="2" class="ng-binding">
                    SeleniumTest &nbsp;
                    <!-- ngIf: user.IsLockedOut -->
                </td>
                <td class="ng-binding">
                    
                </td>
                <th style="width:58px;">
                      <span ng-show="user.AuthorizedFor.indexOf('Operations') != -1" ng-hide="user.AuthorizedFor.indexOf('Operations') == -1"><i class="fa fa-check"></i></span>
                </th>
                <th style="width:58px;">
                      <span ng-show="user.AuthorizedFor.indexOf('Overrides') != -1" ng-hide="user.AuthorizedFor.indexOf('Overrides') == -1"><i class="fa fa-check"></i></span>
                </th>
                <th style="width:58px;">
                      <span ng-show="user.AuthorizedFor.indexOf('Reports') != -1" ng-hide="user.AuthorizedFor.indexOf('Reports') == -1"><i class="fa fa-check"></i></span>
                </th>
                <th style="width:58px;">
                      <span ng-show="user.AuthorizedFor.indexOf('Setup') != -1" ng-hide="user.AuthorizedFor.indexOf('Setup') == -1" class="ng-hide"><i class="fa fa-check"></i></span>
                </th>
                <th style="width:58px;">
                      <span ng-show="user.AuthorizedFor.indexOf('Users') != -1" ng-hide="user.AuthorizedFor.indexOf('Users') == -1" class="ng-hide"><i class="fa fa-check"></i></span>
                </th>
                <th style="width:58px;">
                     <span ng-show="user.RemoteAccessEnabled" ng-hide="!user.RemoteAccessEnabled"><i class="fa fa-check"></i></span>
                </th>
                <td>
                    <label class="btn btn-sm btn-default texture-blue" data-ng-click="editUser(user)">Edit User</label>
                </td>
            </tr>

Answer

You can nest element with text in [] to search its parent tr
and later you can search label in this parent.

'//tr[td[contains(text(), "SeleniumTest")]]//label'

Full working code with example HTML directly in code.

html = '''<table>
<tr ng-repeat="user in userData track by $index" ng-class-odd="'o-table-bkodd'" ng-class-even="'o-table-bkeven'" class="ng-scope o-table-bkeven">
    <td colspan="2" class="ng-binding">
        SeleniumTest &nbsp;
        <!-- ngIf: user.IsLockedOut -->
    </td>
    <td class="ng-binding">

    </td>
    <th style="width:58px;">
        <span ng-show="user.AuthorizedFor.indexOf('Operations') != -1" ng-hide="user.AuthorizedFor.indexOf('Operations') == -1"><i class="fa fa-check"></i></span>
    </th>
    <th style="width:58px;">
        <span ng-show="user.AuthorizedFor.indexOf('Overrides') != -1" ng-hide="user.AuthorizedFor.indexOf('Overrides') == -1"><i class="fa fa-check"></i></span>
    </th>
    <th style="width:58px;">
        <span ng-show="user.AuthorizedFor.indexOf('Reports') != -1" ng-hide="user.AuthorizedFor.indexOf('Reports') == -1"><i class="fa fa-check"></i></span>
    </th>
    <th style="width:58px;">
        <span ng-show="user.AuthorizedFor.indexOf('Setup') != -1" ng-hide="user.AuthorizedFor.indexOf('Setup') == -1" class="ng-hide"><i class="fa fa-check"></i></span>
    </th>
    <th style="width:58px;">
        <span ng-show="user.AuthorizedFor.indexOf('Users') != -1" ng-hide="user.AuthorizedFor.indexOf('Users') == -1" class="ng-hide"><i class="fa fa-check"></i></span>
    </th>
    <th style="width:58px;">
        <span ng-show="user.RemoteAccessEnabled" ng-hide="!user.RemoteAccessEnabled"><i class="fa fa-check"></i></span>
    </th>
    <td>
        <label class="btn btn-sm btn-default texture-blue" data-ng-click="editUser(user)">Edit User</label>
    </td>
</tr>
<tr>
  <td>Other Text</td>
  <td><label>Other Label</label></td>
</tr>
</table>'''

from selenium import webdriver
from selenium.webdriver.common.by import By

# ---

import selenium
print('Selenium:', selenium.__version__)  # Selenium: 4.19.0  # or newer

# ---

#driver = webdriver.Chrome()
driver = webdriver.Firefox()

driver.get("data:text/html;charset=utf-8," + html)
#driver.implicitly_wait(3)

#item = driver.find_element(By.XPATH, '//*[contains(text(), "SeleniumTest")]')
print("Checking: SeleniumTest")
item = driver.find_element(By.XPATH, '//tr[td[contains(text(), "SeleniumTest")]]//label')
print('Found:', item.text)

print("Checking: Other Text")
item = driver.find_element(By.XPATH, '//tr[td[contains(text(), "Other Text")]]//label')
print('Found:', item.text)

Result:

Selenium: 4.31.0

Checking: SeleniumTest
Found: Edit User

Checking: Other Text
Found: Other Label

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles