Selenium Webdriver Python How to click all checkboxes in a table of rows - python-2.7

I have a html page with rows of check boxes. I want to find all checkoxes in the table and click it.
What is the best way I can do this please?
My first attempt I have identified the table which has the check boxes by it's ID
table_id = self.driver.find_element(By.ID, 'data_configuration_datamaps_ct_fields_body')
I then get all the rows
rows = table_id.find_elements(By.TAG_NAME, "tr")
I then use a for loop to iterate through the rows. In each iteration I locate the column
for row in rows:
col_name = row.find_elements(By.TAG_NAME, "td")[0]
I then locate the checkbox from the column and click it.
col_checkbox = col_name.find_elements(By.XPATH, "//input[#type='checkbox']")
col.checkbox.click()
I am doing this wrong. What is the best way to do this?
I am using Selenium Webdriver with Python
My full code snippet is as follows:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
def delete_all_datamaps(self):
try:
WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located((By.TAG_NAME, 'td')))
table_id = self.driver.find_element(By.ID, 'data_configuration_datamaps_ct_fields_body')
rows = table_id.find_elements(By.TAG_NAME, "tr")
print "Rows length"
print len(rows)
for row in rows:
# Get the columns
col_name = row.find_elements(By.TAG_NAME, "td")[0] # This is the 1st column
print "col_name.text = "
print col_name.text
col_checkbox = col_name.find_elements(By.XPATH, "//input[#type='checkbox']")
col.checkbox.click()
except NoSuchElementException, e:
return False
return None
The HTML is:
<table id="data_configuration_datamaps_ct_fields_body" cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GOFU2OVFG GOFU2OVMG" __gwt_subrow="0" __gwt_row="0">
<td class="GOFU2OVEG GOFU2OVGG GOFU2OVHG GOFU2OVNG">
<div __gwt_cell="cell-gwt-uid-185" style="outline-style:none;" tabindex="0">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVGG GOFU2OVNG">
td class="GOFU2OVEG GOFU2OVGG GOFU2OVNG">
td class="GOFU2OVEG GOFU2OVGG GOFU2OVBH GOFU2OVNG">
</tr>
</tbody>
</table>
The following xpath will find the 1st checkbox
//table[#id="data_configuration_datamaps_ct_fields_body"]//tr/td/div/input
I only need to find the checkboxes inside this table.
Thanks,
Riaz

I don't know python but I found some code and I think it will work... or at least be close enough that you can fix it but what you want is a CSS selector.
checkboxes = driver.find_elements_by_css_selector("#data_configuration_datamaps_ct_fields_body input[type='checkbox']")
for checkbox in checkboxes:
checkbox.click()
The CSS selector, #data_configuration_datamaps_ct_fields_body input[type='checkbox'], reads like look for an element with an ID of data_configuration_datamaps_ct_fields_body that has a descendant INPUT element whose type is checkbox.
You will likely need a slight pause in the loop after you click to give the page a fraction of a second to respond to the click. You can try it without and see how it works. If you need a pause, it probably won't need to be long, maybe 50-100ms or so is what I would try.
Here is a CSS Selector reference.

Related

Selenium Python I am trying to iterate rows in a html table I get error Index out of range

I have a webpage with a HTML table with some columns and rows. The user can select a row from the table and click the delete button. This will delete the row from the html table. E.g. In the Name column (index 1) there is a value "Testa"
The user can select the checkbox for the row where Name is "Testa" and delete it.
I would like to iterate over the rows and check "Testa" is not there. This way I can be sure the delete worked.
My code is not iterating over the table.
My code snippet is:
def is_value_deleted_from_user_defined_field(self, name): # return true if the user defined name is null. This method is to verify the user defined field has been deleted
# Params name : The name of the user defined field e.g. AREACODE, Testa
try:
WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'data_configuration_edit_data_object_tab_details_tb_fields')))
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'data_configuration_edit_data_object_tab_details_tb_fields')))
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows:
# Get the columns
col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Name column
print "col_name.text = "
if (col_name.text != name):
return True
return False
except NoSuchElementException, e:
print "Element not found "
print e
self.save_screenshot("is_value_deleted_from_user_defined_field")
return False
My code to call the method is:
self.assertTrue(data_objects_edit_page.is_value_deleted_from_user_defined_field("Testa"), "User Defiend field Testa has not been deleted")
The HTML snippet is:
<table id="data_configuration_edit_data_object_tab_details_tb_fields" class="GFNQNVHJE border" cellspacing="0" __gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true">
<thead aria-hidden="false">
<colgroup>
<tbody style="">
<tr class="GFNQNVHCD GFNQNVHMD" __gwt_subrow="0" __gwt_row="0">
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHED GFNQNVHLD GFNQNVHND">
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHND">
<div __gwt_cell="cell-gwt-uid-407" style="outline-style:none;">
<input id="" class="" type="text" style="color: black;" value="AREACODE"/>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHND">
<div __gwt_cell="cell-gwt-uid-408" style="outline-style:none;">
<select tabindex="-1">
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHOD GFNQNVHND">
<div __gwt_cell="cell-gwt-uid-409" style="outline-style:none;">
<input id="" class="" type="text" style="color: black;" value="50"/>
</div>
</td>
</tr>
<tr class="GFNQNVHCE GFNQNVHJD" __gwt_subrow="0" __gwt_row="1">
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHED GFNQNVHKD">
<div __gwt_cell="cell-gwt-uid-406" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHKD">
<div __gwt_cell="cell-gwt-uid-407" style="outline-style:none;">
<input id="" class="" type="text" style="color: black;" value="VSEQ"/>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHKD">
<div __gwt_cell="cell-gwt-uid-408" style="outline-style:none;">
<select tabindex="-1">
<option value="Integer">Integer</option>
<option selected="selected" value="Text string">Text string</option>
<option value="Date/time">Date/time</option>
<option value="Floating point">Floating point</option>
</select>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHOD GFNQNVHKD">
</tr>
</tbody>
<tbody style="display: none;">
<tfoot style="display: none;" aria-hidden="true"/>
</table>
The error I get is:
Traceback (most recent call last):
File "E:\test_runners 2 edit project - add more tests for Regression\selenium_regression_test_5_1_1\Regression_TestCase\RegressionProjectEdit_TestCase.py", line 951, in test_000033_Data_Objects_edit_ACVSEQ2_and_save_edited_changes
self.assertTrue(data_objects_edit_page.is_value_deleted_from_user_defined_field("Testa"), "User Defiend field Testa has not been deleted")
File "E:\test_runners 2 edit project - add more tests for Regression\selenium_regression_test_5_1_1\Pages\data_objects_edit.py", line 502, in is_value_deleted_from_user_defined_field
col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Name column
IndexError: list index out of range
How do I iterate over the table and check "Testa" or for example "AREACODE" is not in the table?
"AREACODE" is in the HTML snippet above. I think it is at index column 1
Thanks, Riaz
IndexError: list index out of range
Actually you're passing hard coded index without checking it's length to determine whether column present or not after deleting the column, that's why it is throwing exception which is absolutely correct because after deleting column from desired row there is no more desire column element present at provided index.
You should try to check column elements length instead to determine whether deleted column element exists or not as below :-
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows:
cols = row.find_elements(By.TAG_NAME, "td")
if len(cols) > 1 and cols[1].text == name :
return False
return True
It seems to be just getting the header of the table and stopping there. It won't go to the next line which is cols = row.find_elements(By.TAG_NAME, "td")
Actually you need to return True after for loop as below :-
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows :
cols = row.find_elements(By.TAG_NAME, "td")
if len(cols) > 1 and cols[1].text == name :
return False
return True
I could use self.driver.page_source and check in the page source if the text is there or not
If you just want to determine desire text exists on the page or not after delete, you can try as below instead :-
if len(driver.find_elements_by_xpath(".//table[#id='data_configuration_edit_data_object_tab_details_tb_fields']//*[text()= '"+name+"']")) > 0 :
return False
return True

Selenium Python I want to check an element does not have a value I get the error NoSuchElementException: Message: Unable to find element with xpath

I have a HTML table with some rows and columns. I can get the value I want from for a row from column 3 which has the value "14"
When a user deletes a record from the GUI I would like to check that 14 is not present anymore.
I get the error:
NoSuchElementException: Message: Unable to find element with xpath == //table[#id="reporting_view_report_dg_main_body"]//tr//td[3]/div/span[#title="14"]
My XPATH to find the value is:
usn_id_element = self.get_element(By.XPATH, '//table[#id="reporting_view_report_dg_main_body"]//tr//td[3]/div/span[#title="14"]')
My function routine to check the value is not there is
def is_usn_id_not_displayed_in_all_records_report_results(self, usn_id): # When a record has been disconnected call this method to check the record for usn id is not there anymore.
usn_id_element = self.get_element(By.XPATH, '//table[#id="reporting_view_report_dg_main_body"]//tr//td[3]/div/span[#title="14"]')
print "usn_id_element"
print usn_id_element
print usn_id_element.text
if usn_id not in usn_id_element:
return True
get_element routine:
from selenium.webdriver.common.by import By
# returns the element if found
def get_element(self, how, what):
# params how: By locator type
# params what: locator value
try:
element = self.driver.find_element(by=how, value=what)
except NoSuchElementException, e:
print what
print "Element not found "
print e
screenshot_name = how + what + get_datetime_now() # create screenshot name of the name of the element + locator + todays date time. This way the screenshot name will be unique and be able to save
self.save_screenshot(screenshot_name)
raise
return element
The HTML snippet is:
<table id="reporting_view_report_dg_main_body" cellspacing="0" style="table-layout: fixed; width: 100%; margin-bottom: 17px;">
<colgroup>
<tbody>
<tr class="GFNQNVHJM" __gwt_subrow="0" __gwt_row="0"\>
<tr class="GFNQNVHIN" __gwt_subrow="0" __gwt_row="1"\>
<div __gwt_cell="cell-gwt-uid-9530" style="outline-style:none;">
<span title="14" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">14</span>
</div>
</td>
<td class="GFNQNVHIM GFNQNVHKM"\>
<td class="GFNQNVHIM GFNQNVHKM"\>
</tr>
<tr class="GFNQNVHIN" __gwt_subrow="0" __gwt_row="13">
<td class="GFNQNVHIM GFNQNVHJN GFNQNVHLM">
<td class="GFNQNVHIM GFNQNVHJN">
<td class="GFNQNVHIM GFNQNVHJN">
<div __gwt_cell="cell-gwt-uid-9530" style="outline-style:none;">
<span class="" title="14" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">14</span>
</div>
</td>
<td class="GFNQNVHIM GFNQNVHJN"\>
<td class="GFNQNVHIM GFNQNVHJN"\>
</tr>
<tr class="GFNQNVHJM" __gwt_subrow="0" __gwt_row="14"\>
<tr class="GFNQNVHIN" __gwt_subrow="0" __gwt_row="15"\>
</tbody>
</table>
How can check if the value is not there?
Thanks, Riaz
Right now you are checking the attribute 'title' has a value of 14 and not the contents of the cell. What happens after the delete occurs? Does the span remain in the cell? Does the value of the cell becomes blank and does the value of the attribute 'title' also becomes blank?
The xpath below checks that the value of the cell is blank after deletion. Assumption you get a blank cell after deletion.
"//table[#id='reporting_view_report_dg_main_body']//tr//td[3]/div/span[.='']"
If you wanna check with value of title after deletion
"//table[#id='reporting_view_report_dg_main_body']//tr//td[3]/div/span[not(#title='14')]"

BeautifulSoup Python printing out the extracted data from a table the 2nd column is dropping onto a new line. How ot keep it on same line

I have extracted the data I require from the HTML using BeautifulSoup. I am printing out the data into an email. The data from the 2nd column where it says "pass" is dropping onto a newline in the email body. I would like to keep the "pass" text onto the same line as the test case name.
The sample email body is:
ClearCore 5_1_1 Automated GUI Test_IE11_Selenium_VM Test Report
Status: Pass 89 Error 1
test_000001_login_valid_user
pass
test_000002_select_a_project
pass
test_000003_verify_Lademo_CRM_DataPreview_is_present
pass
test_000004_view_data_preview_Lademo_CRM_and_test_scrollpage
pass
I would like the output to be (would be nice to have the pass aligned nicely in a column):
ClearCore 5_1_1 Automated GUI Test_IE11_Selenium_VM Test Report
Status: Pass 89 Error 1
test_000001_login_valid_user pass
test_000002_select_a_project pass
test_000003_verify_Lademo_CRM_DataPreview_is_present pass
test_000004_view_data_preview_Lademo_CRM_and_test_scrollpage pass
My code to extract the data is:
def extract_testcases_from_report_htmltestrunner():
filename = (r"E:\test_runners 2 edit project\selenium_regression_test_5_1_1\TestReport\ClearCore501_Automated_GUI_TestReport.html")
html_report_part = open(filename,'r')
soup = BeautifulSoup(html_report_part, "html.parser")
for div in soup.select("#result_table tr div.testcase"):
yield div.text.strip().encode('utf-8'), div.find_next("a").text.strip().encode('utf-8')
My email code:
from email.mime.text import MIMEText
def send_report_summary_from_htmltestrunner_selenium_report():
msg = MIMEText("\n ClearCore 5_1_1 Automated GUI Test_IE11_Selenium_VM Test Report \n " + "\n" +
"".join([' - '.join(seq) for seq in extract_status_from_report_htmltestrunner()]) + "\n\n" +
'\n'.join([elem
for seq in extract_testcases_from_report_htmltestrunner()
for elem in seq]) + "\n" +
"\n Report location = : \\\storage-1\Testing\Selenium_Test_Report_Results\ClearCore_5_1_1\Selenium VM\IE11 \n")
msg['Subject'] = "ClearCore 5_1_1 Automated GUI Test"
msg['to'] = "cc4_server_dev#company.onmicrosoft.com"
msg['From'] = "system#company.com"
s = smtplib.SMTP()
s.connect(host=SMTP_SERVER)
s.sendmail(msg['From'], msg['To'], msg.as_string())
s.close()
How can i format it so pass is nearly aligned on the same line as the test case name? Instead of pass dropping onto a new line every time.
Thanks, Riaz
The HTML snippet is if it helps:
<table id='result_table'>
<colgroup>
<col align='left' />
<col align='right' />
<col align='right' />
<col align='right' />
<col align='right' />
<col align='right' />
</colgroup>
<tr id='header_row'>
<td>Test Group/Test case</td>
<td>Count</td>
<td>Pass</td>
<td>Fail</td>
<td>Error</td>
<td>View</td>
</tr>
<tr class='passClass'>
<td>Regression_TestCase.RegressionProjectEdit_TestCase.RegressionProject_TestCase_Project_Edit</td>
<td>75</td>
<td>75</td>
<td>0</td>
<td>0</td>
<td>Detail</td>
</tr>
<tr id='pt1.1' class='hiddenRow'>
<td class='none'><div class='testcase'>test_000001_login_valid_user</div></td>
<td colspan='5' align='center'>
<!--css div popup start-->
<a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.1')" >
pass</a>
<div id='div_pt1.1' class="popup_window">
<div style='text-align: right; color:red;cursor:pointer'>
<a onfocus='this.blur();' onclick="document.getElementById('div_pt1.1').style.display = 'none' " >
[x]</a>
</div>
<pre>
pt1.1: *** test_login_valid_user ***
test login with a valid user - Passed
</pre>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='pt1.2' class='hiddenRow'>
<td class='none'><div class='testcase'>test_000002_select_a_project</div></td>
<td colspan='5' align='center'>
<!--css div popup start-->
<a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.2')" >
pass</a>
<div id='div_pt1.2' class="popup_window">
<div style='text-align: right; color:red;cursor:pointer'>
<a onfocus='this.blur();' onclick="document.getElementById('div_pt1.2').style.display = 'none' " >
[x]</a>
</div>
<pre>
pt1.2: *** test_login_valid_user ***
test login with a valid user - Passed
*** test_select_a_project ***
08_12_1612_08_03
Selenium_Regression_Edit_Project_Test
</pre>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='pt1.3' class='hiddenRow'>
<td class='none'><div class='testcase'>test_000003_verify_Lademo_CRM_DataPreview_is_present</div></td>
<td colspan='5' align='center'>
<!--css div popup start-->
<a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.3')" >
pass</a>
<div id='div_pt1.3' class="popup_window">
<div style='text-align: right; color:red;cursor:pointer'>
<a onfocus='this.blur();' onclick="document.getElementById('div_pt1.3').style.display = 'none' " >
[x]</a>
</div>
<pre>
pt1.3: *** test_login_valid_user ***
test login with a valid user - Passed
*** test_select_a_project ***
08_12_1612_08_03
Selenium_Regression_Edit_Project_Test
*** Test verify_Lademo_CRM_DataPreview_is_present ***
aSelenium_LADEMO_CRM_DONOTCHANGE
File
498
</pre>
</div>
<!--css div popup end-->
</td>
</tr>
The issue that you're having is that your code returns the items from extract_testcases_from_report_htmltestrunner() in a singular list that it then joins with the '\n' character. As a simple example, try this test code that replicates your code:
def test_yield(n):
for i in range(n):
yield str(i), str(i+1)
print '\n'.join([elem for seg in test_yield(5) for elem in seg])
That code should return the string: '0\n1\n1\n2\n2\n3\n3\n4\n4\n5'
You need to loop over the elements that come back from your function above and first join those with either a TAB (\t) character, or, better yet, feed those data elements into the framework of an HTML table array if your email message is HTML enabled. Here's a demo of the \t then \n approach, but you can add strings and formatting to make the HTML Table method work:
'\n'.join(elem for elem in ['\t'.join(e) for e in test_yield(5)])
This will first create a list of the elements of test_yield(), then separate those elements with a '\t', then separate those strings with a '\n'
Hope this helps.
(EDIT: Adding Commentary on Creating a 2-Column Effect)
Following comments asking about creating the effect of 2-columns w/o the ability to use HTML tables, you can do something like the following, which uses spacing instead of TABs for consistency and easier coding in your overall package:
from random import randint
def test_yield(n):
for i in range(n):
yield 'A'*(randint(1,10)), 'PASS'
test_lbls = [y for y in test_yield(10)]
max_len = max(len(i[0]) for i in test_lbls)
test_lbls = [(i[0]+' '*((max_len-len(i[0]))+1),i[1]) for i in test_lbls]
for l in test_lbls:
print l[0]
For my test case, it generated output like this:
AAAAAA PASS
AAAA PASS
AAAAA PASS
AAA PASS
A PASS
AAAAA PASS
AAAAAAAA PASS
AAA PASS
AAAAAAAAA PASS
AAAAAAA PASS
You'll have to modify this to work with your function, but the algorithm for space padding should work all the same! GL

Selenium Webdriver Python How do you wait for text of an element to appear after clicking a button and keep trying until text appears

I have a html table of with some columns. Each row shows the name of a report
I can select a report and click the run button to process the reports.
The text "view" will appear in the View column after i click on the Reports button.
The "view" text will not appear on it's own.
It can be a few clicks until the text appears.
I want to keep clicking the Reports button until the "view" text appears
I think the best solution would be to put this in a while loop somehow.
I have tried but I get the error:
UnboundLocalError: local variable 'element' referenced before assignment
Error Trace is:
Error
Traceback (most recent call last):
File "C:\Webdriver\ClearCore\TestCases\ReportingPage_TestCase.py", line 81, in test_1_add_matches_report
print reports_page.is_view_link_present_to_view_the_report("Matches")
File "C:\Webdriver\ClearCore\Pages\reports.py", line 321, in is_view_link_present_to_view_the_report
view_element = self.get_element(By.XPATH, '//table[#id="reporting_reports_ct_fields_body"]//td[.//span[text()="%s"]]/following-sibling::td[2]//span[text()="view"]' % report_name)
File "C:\Webdriver\ClearCore\Pages\base.py", line 34, in get_element
return element
UnboundLocalError: local variable 'element' referenced before assignment
The method with the While loop to wait for element to be found is:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
class ReportsPage(BasePage):
def __init__(self, d):
super(ReportsPage, self).__init__(d)
self.datamap_name = UsefulHelperMethods.read_from_file("datamap_name")
self.tool_bar = ToolbarPage(self.driver)
def is_view_link_present_to_view_the_report(self, report_name):
# Params : report_name : Name of the report which to select to view
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'reporting_reports_ct_fields_body')))
found = False
while not found:
try:
view_element = self.driver.find_element(By.XPATH, '//table[#id="reporting_reports_ct_fields_body"]//td[.//span[text()="%s"]]/following-sibling::td[2]//span[text()="view"]' % report_name)
found = True
except NoSuchElementException:
time.sleep(2)
self.tool_bar.click_reports_button_from_toolbar()
get element defined in my Base Class is:
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
class BasePage(object):
def __init__(self, driver):
self.driver = driver
self.driver.implicitly_wait(120)
# returns the element if found
def get_element(self, how, what):
# params how: By locator type
# params what: locator value
try:
element = self.driver.find_element(by=how, value=what)
except NoSuchElementException, e:
print what
print "Element not found "
print e
return element
My TestCase class which calls the method is:
from Menus.project_navigator import ProjectNavigatorPage
from Menus.toolbar import ToolbarPage
from Pages.reports import ReportsPage
class ReportingPage_TestCase(BaseTestCase):
def test_1_add_matches_report(self):
tool_bar = ToolBarPage(self.driver)
project_navigator = ProjectNavigatorPage(self.driver)
reports_page = project_navigator.select_projectNavigator_item("Reports")
reports_page.click_add_button_for_reports()
reports_page.select_a_report_checkbox_from_reports_page("Matches")
reports_page.click_run_button_to_run_the_report()
reports_page.click_ok_from_reports_dialog()
tool_bar.click_reports_button_from_toolbar()
print reports_page.is_view_link_present_to_view_the_report("Matches")
How can I keep clicking on the reports button (say every 2 secs) and check if the "view" text is present. Keep trying for about 5 mins.
If at the end of 5 mins it still does not find the view link then to print view text not found, test failed?
I don't want to use time.sleep as that is not effient. The view text could appear in few seconds or a minute depening on how large the report is.
Thanks, help appreciated.
Riaz
The HTML is:
<table id="reporting_reports_ct_fields_body" cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GLKP2TGBFG GLKP2TGBMG" __gwt_subrow="0" __gwt_row="0">
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBHG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7232" style="outline-style:none;" tabindex="0">
<input type="checkbox" tabindex="-1" />
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7233" style="outline-style:none;">
<span class="linkhover" title="Matches" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Matches</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7234" style="outline-style:none;">
<span class="" title="manual" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">manual</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7235" style="outline-style:none;">
<span class="linkhover block" title="view" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">view</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7236" style="outline-style:none;">
<span class="" title="Matches report" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">Matches report</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7237" style="outline-style:none;">
<span class="" title="USN entities" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">USN entities</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7238" style="outline-style:none;">
<span class="" title="05/11/2015 15:24:47" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">05/11/2015 15:24:47</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7239" style="outline-style:none;">
<span class="block" title="" style="">12</span>
</div>
</td>
<td class="GLKP2TGBEG GLKP2TGBGG GLKP2TGBBH GLKP2TGBNG">
<div __gwt_cell="cell-gwt-uid-7240" style="outline-style:none;">
<span class="" title="INFOSHARE\riaz.ladhani" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">COMPANY\riaz.ladhani</span>
</div>
</td>
</tr>
<tr class="GLKP2TGBEH" __gwt_subrow="0" __gwt_row="1">
</tbody>
element only exists in your try block you must define it outside of a try block. In pseudo code it would look like:
try
{
var element;
}
...
return element; // but does not exist in this scope here
just return it in your try and you're fine, no need for the extra line:
try:
return self.driver.find_element(by=how, value=what)
except NoSuchElementException, e:
print what
print "Element not found "
print e
return None
to continously click the button you can use WebDriverWait (you need to return None if the element was not found in your get_element for this to work).
create a new method that will click and check for the element
def clickTillView:
reportElement.click()
return get_element(self, how, what) != None
then you can wait for clickTillView to be true ergo the element exists
new WebDriverWait(driver, 10000, 1, None).until(clickTillView(), "view was not found in time")
Forgive my Python mistakes, I'm a Java guy :p but this is basically how you can solve it.

I have a table of rows with checkboxes in columns. How do i select a particular checkbox

I have the following HTML structure. A table with rows, the 2nd column has the text displayed e.g. Title (in row 1), FName (in row 2), SNAME (in row3), GENDER etc.
The 3rd column has a checkbox for each row.
I am trying to select a particular checkbox. E.g. my method will accept a parameter (the name of the text value in the row e.g. TITLE).
The method will select the checkbox for TITLE.
When i call the method again with parameter FNAME, the checkbox for FNAME will be clicked.
I am using Selenium Webdriver with Python
I have tried the following XPATH to identify the checkbox:
//span[#title="TITLE" and contains(text(), "TITLE")]/following-sibling::*
//span [text()="TITLE"]/../../preceding-sibling::td/div/input[#type="checkbox"]
These do not find the checkbox for the row called TITLE
I can get to the TITLE with the following XPATH.
//span [text()="TITLE"]
My code snippet is:
def add_mapping2(self, name):
try:
checkbox = self.driver.find_element(By.XPATH, '//span [text()="+name+"]/../../preceding-sibling::td/div/input[#type="checkbox"]')
checkbox.click()
except NoSuchElementException, e:
return False
return True
From my unittest.Testcase class I call the method as follows:
class MappingsPage_TestCase(BaseTestCase):
def test_add_mappings(self):
mappingsPage = projectNavigator.select_projectNavigator_item("Mappings")
mappingsPage.add_mapping2("TITLE")
mappingsPage.add_mapping2("SNAME")
The HTML is:
<table id="data_configuration_edit_mapping_tab_mappings_ct_mapping_body" cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="0">
<tr class="GOFU2OVEH GOFU2OVGH GOFU2OVPG GOFU2OVMG" __gwt_subrow="0" __gwt_row="1">
<td class="GOFU2OVEG GOFU2OVFH GOFU2OVHG GOFU2OVHH GOFU2OVAH GOFU2OVNG">
<td class="GOFU2OVEG GOFU2OVFH GOFU2OVHH GOFU2OVAH GOFU2OVNG">
<div __gwt_cell="cell-gwt-uid-792" style="outline-style:none;">
<span title="TITLE" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">TITLE</span>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVFH GOFU2OVHH GOFU2OVBH GOFU2OVOG GOFU2OVAH GOFU2OVNG">
<div __gwt_cell="cell-gwt-uid-793" style="outline-style:none;" tabindex="0">
<input type="checkbox" checked="" tabindex="-1"/>
</div>
</td>
</tr>
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="2">
<td class="GOFU2OVEG GOFU2OVGG GOFU2OVHG">
<div __gwt_cell="cell-gwt-uid-791" style="outline-style:none;">
<input type="radio" name="rbCrossRow124"/>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVGG">
<div __gwt_cell="cell-gwt-uid-792" style="outline-style:none;">
<span class="" title="FNAME" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">FNAME</span>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVGG GOFU2OVBH">
<div __gwt_cell="cell-gwt-uid-793" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
</tr>
<tr class="GOFU2OVEH" __gwt_subrow="0" __gwt_row="3">
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="4">
<tr class="GOFU2OVEH" __gwt_subrow="0" __gwt_row="5">
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="6">
more rows with names with checkboxes etc......
</tbody>
</table>
What XPATH could I use to get the checkbox for TITLE, FNAME etc?
I have the table ID "data_configuration_edit_mapping_tab_mappings_ct_mapping_body"
Maybe there is a way to start from the table ID and use a for loop to iterate through the rows and find the particular checkbox?
Thanks.
Riaz
you would use the following xpath expression
String xpath = "//span[#title = 'TITLE']/ancestor::tr[1]//input[#type = 'checkbox']"
What it does:
first search for a span element with your parameter (pls change 'TITLE' to the variable you are using)
then find the first ancestor element that is a tr-element
from there find the input element that is your checkbox within this tr-element
You could then refine to sth like this:
WebElement table = driver.findElement(By.id("data_configuration_edit_mapping_tab_mappings_ct_mapping_body"));
WebElement checkbox = table.findElement(By.xpath(xpath));
For the interest of others whom come across a similar problem. My Python code which I have used for the above answer is:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
def add_mapping(self, name):
wait = WebDriverWait(self.driver, 10)
try:
checkbox = wait.until(EC.element_to_be_clickable((By.XPATH, '//span[#title = "%s"]/ancestor::tr[1]//input[#type = "checkbox"]' % name)))
#table_id = self.driver.find_element(wait.until(EC.element_to_be_clickable(By.ID, 'data_configuration_edit_mapping_tab_mappings_ct_mapping_body')))
#checkbox = table_id.find_element(By.XPATH, '//span[#title = "TITLE"]/ancestor::tr[1]//input[#type = "checkbox"]')
checkbox.click()
except NoSuchElementException, e:
return False
return True
The table id i commented out also works.