Search code examples
pythonseleniumautomated-testswebdriver

Click a button in a table, but all rows contain automatically generated identical buttons in Selenium


I am currently doing QA Automation on a web application with Selenium WebDriver, and the language I decided to use is Python 3. Everything was going great until I got stuck on reaching a specific element in a table.

Some context:

This table allows for User Management. It means that new rows with users and their permissions are automatically added. The permissions are also buttons and can be easily removed just by a single click by the admin (for example, he will click on the LOGIN permission of test01 and he will revoke his permissions to login). There is also the "+" button to add a permission. Here is the example table:

+----------+-------------+--------------------+
| username | displayName | Permission         |
+----------+-------------+--------------------+
| test01   | Test, User  | LOGIN ( + )        |
+----------+-------------+--------------------+
| test02   | User, Test  | LOGIN ADMIN ( + )  |
+----------+-------------+--------------------+

The thing is, I want Selenium to click on the LOGIN button of test01, so his permissions to login will be revoked. However, I am having difficulties pointing Selenium to that specific element. When I click "inspect" this is the browser information.

<table id="permissions" class="rounded-large">
  <tbody>
<tr>
<td>test01</td>
  <td>Selenium User</td>
    <td>                                                  #i want this
      <span class="perm-control perm clickable rounded-small">LOGIN</span>
      <span class="perm-control add-perm clickable rounded-small">+</span>
    </td>
</tr>

<tr>
<td>test02</td>
  <td>Selenium Admin</td>
    <td>
      <span class="perm-control perm clickable rounded-small">LOGIN</span>
      <span class="perm-control add-perm clickable rounded-small">+</span>
    </td>
</tr>
<thead>
      <tr>
        <th>Username</th>
        <th>Display Name</th>
        <th class="centered">Permissions</th>
      </tr>
    </thead>
    <tbody>
  </tbody>

There is no id, or class to this element (which is auto generated, as this table can expand with 30-40 users) and I am not sure how to click this exact LOGIN button and not the one of test02 for example. It is not an option to change the source code currently. Thank you!


Solution

  • To click on Selenium User LOGIN button induce WebDriverWait and element_to_be_clickable and following xpath

    WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//table[@id='permissions']//td[text()='Selenium User']/following::td[1]/span[text()='LOGIN']"))).click()
    

    OR

    WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//table[@id='permissions']//td[text()='test01']/following::td[2]/span[text()='LOGIN']"))).click()
    

    To execute above code you need to imports followings.

    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC