简体   繁体   中英

Click on check box after confirming text in html table which is dynamic

I need to click on the check box in the HTML table after asserting the text. Below is the html.

<div class="k-widget k-grid ">
    <div class="k-grid-header" style="padding: 0px 16px 0px 0px;">
        <div class="k-grid-header-wrap">
            <table>
                <colgroup>
                    <col width="50px">
                    <col>
                    <col>
                </colgroup>
                <thead>
                    <tr>
                        <th aria-sort="" colspan="1" rowspan="1" class="k-header checkbox-grid-column"><input id="c3c07f7e-5119-4a36-9f67-98fa4d21fa07" type="checkbox" class="k-checkbox"><label class="k-checkbox-label" for="c3c07f7e-5119-4a36-9f67-98fa4d21fa07"></label></th>
                        <th aria-sort="" colspan="1" rowspan="1" class="k-header"><a class="k-link">Permission</a></th>
                        <th aria-sort="" colspan="1" rowspan="1" class="k-header"><a class="k-link">Description</a></th>
                    </tr>
                </thead>
            </table>
        </div>
    </div>
    <div class="k-grid-container">
        <div class="k-grid-content k-virtual-content">
            <div style="position: relative;">
                <table tabindex="-1" class="k-grid-table">
                    <colgroup>
                        <col width="50px">
                        <col>
                        <col>
                    </colgroup>
                    <tbody>
                        <tr class="k-master-row">
                            <td colspan="1" class="checkbox-grid-column"><input id="c8711bab-702a-43b9-8a75-02ad06a8baa3" type="checkbox" class="k-checkbox"><label class="k-checkbox-label" for="c8711bab-702a-43b9-8a75-02ad06a8baa3"></label></td>
                            <td>ACCESSGROUP_BULKDELETE</td>
                            <td colspan="1">Enable Bulk Delete button in access group management</td>
                        </tr>
                        <tr class="k-master-row k-alt">
                            <td colspan="1" class="checkbox-grid-column"><input id="a029bc1e-53d8-4328-89ce-6640363d515a" type="checkbox" class="k-checkbox"><label class="k-checkbox-label" for="a029bc1e-53d8-4328-89ce-6640363d515a"></label></td>
                            <td>ACCESSGROUP_DELETE</td>
                            <td colspan="1">Enable Delete Button in the access group details page</td>
                        </tr>
                        <tr class="k-master-row">
                            <td colspan="1" class="checkbox-grid-column"><input id="645f8474-9840-48e2-a02c-112178aaf5e2" type="checkbox" class="k-checkbox"><label class="k-checkbox-label" for="645f8474-9840-48e2-a02c-112178aaf5e2"></label></td>
                            <td>ACCESSGROUP_NEW</td>

I was able to get text from the TR with the code mentioned

table_id = context.driver.find_elements(By.XPATH, '//*[@id="root"]//table//tbody//tr//td[1]')
    print (table_id)
    # get all of the rows in the table
    #rows = table_id.find_elements(By.TAG_NAME, "tr")
    #for row in rows:
        #permission = row.find_elements(By.TAG_NAME, 'td')[1]
        #print (permission.text)

But I need to iterate through and find exact text and then click the check box.

The locator that you want is an XPath because XPath lets you find an element based on contained text.

//tr[./td[.='ACCESSGROUP_BULKDELETE']]//input
^ find a TR
    ^ that has a child TD that contains the desired text
                                      ^ then find the descendant INPUT of that TR

You can replace the 'ACCESSGROUP_BULKDELETE' text with whichever label you want in the table. I would take this a step further and put this into a method and pass in the label text as a parameter so you can make it reusable.

You can easily click on the associated check box with respect to the desired text eg ACCESSGROUP_BULKDELETE , ACCESSGROUP_DELETE , ACCESSGROUP_NEW , etc writing a function as follows:

def click_item(item_text):
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[.='" + item_text + "']//preceding::td[1]//label[@for]"))).click()

Now you can call the function passing any of the labels as a string arguments as follows:

click_item("ACCESSGROUP_BULKDELETE")
# or
click_item("ACCESSGROUP_DELETE")
# or
click_item("ACCESSGROUP_NEW")

If you want to locate the relevant checkbox which corresponds to some given text use the following expression:

//td[text()='ACCESSGROUP_BULKDELETE']/preceding-sibling::td/input

Demo:

在此处输入图片说明

In the above expression

Below is code in java....you can relate it with Python. Hope this helps

String rowXpath = "//*[@id='root']//table//tbody//tr[INDEX]" //xpath to find no of rows
noOfRows = context.driver.find_elements(By.XPATH, "//*[@id='root']//table//tbody//tr") //get the count of row

for(int i=1; i<= noOfRows; i++){


    String currXpath = rowXpath.replace(INDEX, i) //update xpath to point to curent row
    currXpath = currXpath+/td[2] //Find xpath of chkBox for current tr in loop

    String chkBoxXpath = currXpath+"/td[1]" //xpath to point to 1st td under current tr in loop

    String currentText = context.driver.find_element(By.XPATH, currXpath).getText(); //find text in 2nd td current row in loop

    if(currentText.equals("ACCESSGROUP_BULKDELETE")){ //Compare with any text of your interest //chk if text found above macthes with your interested text 
        context.driver.find_element(By.XPATH, chkBoxXpath).click(); //click on the 1st td(chkbox) for the  tr which contains your text
    }
}

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