简体   繁体   中英

Selenium selecting first row in a table even though I'm iterating through the rows

I'm really not sure what's going on here and cannot figure it out so hoping someone can help me.

Essentially, I am selecting a table, then finding all of the rows within that table. From here, I am looping through the rows and selecting three checkboxes and checking if they are selected or not. However, the results I am getting for every row is always what the first row is. For example

False True False

then...

False True False

when it should change each row.

Python/Selenium code:

table = driver.find_element_by_xpath("//table[@id='tableMscRatesModal']/tbody")
rows = table.find_elements(By.XPATH, "//tr[@class='ng-scope']") # get all of the rows in the tables

for row in rows:
    print(row.text)

    manager_box = row.find_element_by_xpath("//td/input[@type='radio'][contains(@name, 'userRole')][@value='1']")
    standard_box = row.find_element_by_xpath("//td/input[@type='radio'][contains(@name, 'userRole')][@value='2']")
    no_box = row.find_element_by_xpath("//td/input[@type='radio'][contains(@name, 'userRole')][@value='3']")

    print(manager_box.is_selected())
    print(standard_box.is_selected())
    print(no_box.is_selected())

    if not (manager_box.is_selected() or standard_box.is_selected() or no_box.is_selected()):
        standard_box.send_keys(Keys.SPACE)

I have included an example of two rows below. This is repeated exactly the same for x amount of rows.

HTML:

<table id="tableMscRatesModal" ng-table="tableParams" class="table table-striped table-bordered" show-filter="false">
    <colgroup>
        <col span="1" style="width: 13%;">
            <col span="1" style="width: 13%;">
                <col span="1" style="width: 8%;">
                    <col span="1" style="width: 8%;">
                        <col span="1" style="width: 8%;">
                            <col span="1" style="width: 25%;">
                                <col span="1" style="width: 25%;">
    </colgroup>
    <tbody>
        <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Manager</th>
            <th>Standard user</th>
            <th>No access</th>
            <th>Proposed change</th>
            <th ng-show="iAmRequestManagerWithProposals(getUserList())" class="ng-hide">
                Approval
                <br>
                <br>
                <div class="row approvals">
                    <div class="col-xs-12">
                        <div class="input-group">
                            <span class="input-group-addon">
                                <label ng-click="rejectAll()">
                                    <input type="radio" name="rejectapproveall" id="rejectall" value="rejectall">
                                    Reject all
                                </label>
                            </span>
                            <span class="input-group-addon">
                                <label ng-click="approveAll()">
                                    <input type="radio" name="rejectapproveall" id="acceptall" value="acceptall">
                                    Approve all
                                </label>
                            </span>
                        </div>
                    </div>
                </div>
            </th>
        </tr>
        <!-- ngRepeat: accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName'] -->
        <tr ng-repeat="accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName']" class="ng-scope">
            <td class="ng-binding">First Name</td>
            <td class="ng-binding">Last Name</td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.manager" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="1">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.stdUser" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="2">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.noAccess" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="3">
            </td>
            <td>
                <span ng-show="accessUser.proposedRoleId" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="getRoleChangeProposal(accessUser)" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    Pending manager approval
                </span>
                <span ng-show="accessUser.isAmsAdmin" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="amsAdminUserTooltip" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    AMS admin user
                </span>
            </td>
            <td ng-show="iAmRequestManagerWithProposals(getUserList())" class="ng-hide">

                <div class="row approvals">
                    <div class="col-xs-12">
                        <div class="input-group ng-hide" ng-show="accessUser.proposedRoleId &amp;&amp; accessUser.proposedRoleId > 0">
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.rejected)">
                                    <input type="radio" name="rejectapprove" id="reject" value="rejected" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Reject
                                </label>
                            </span>
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.approved)">
                                    <input type="radio" name="rejectapprove" id="accept" value="approved" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Approve
                                </label>
                            </span>
                        </div>
                    </div>
                </div>

            </td>
        </tr>
        <!-- end ngRepeat: accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName'] -->
        <tr ng-repeat="accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName']" class="ng-scope">
            <td class="ng-binding">First Name</td>
            <td class="ng-binding">Last Name</td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.manager" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="1">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.stdUser" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="2">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.noAccess" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="3">
            </td>
            <td>
                <span ng-show="accessUser.proposedRoleId" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="getRoleChangeProposal(accessUser)" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    Pending manager approval
                </span>
                <span ng-show="accessUser.isAmsAdmin" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="amsAdminUserTooltip" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    AMS admin user
                </span>
            </td>
            <td ng-show="iAmRequestManagerWithProposals(getUserList())" class="ng-hide">

                <div class="row approvals">
                    <div class="col-xs-12">
                        <div class="input-group ng-hide" ng-show="accessUser.proposedRoleId &amp;&amp; accessUser.proposedRoleId > 0">
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.rejected)">
                                    <input type="radio" name="rejectapprove" id="reject" value="rejected" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Reject
                                </label>
                            </span>
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.approved)">
                                    <input type="radio" name="rejectapprove" id="accept" value="approved" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Approve
                                </label>
                            </span>
                        </div>
                    </div>
                </div>

            </td>
        </tr>

Thanks in advance!

When locating an element from another element with xpath you need to use current context .

for row in rows:
    manager_box = row.find_element_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')][@value='1']")
    standard_box = row.find_element_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')][@value='2']")
    no_box = row.find_element_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')][@value='3']")

You can also simplify your code if you use list

checkboxes = row.find_elements_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')]")
for checkbox in checkboxes:
    print(checkboxes.is_selected())

And even farther if you drop the print(row)

checkboxes = row.find_elements_by_xpath("//table[@id='tableMscRatesModal']/tbody//tr[@class='ng-scope']//td/input[@type='radio']")
for i in range(0, len(checkboxes), 3):
    print(checkboxes[i].is_selected())
    print(checkboxes[i + 1].is_selected())
    print(checkboxes[i + 2].is_selected())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM