Let's say I'm working with a webpage table element with an HTML tree like this:
<table>
<tr row-number="1">
<td value="0-SELECTABLE_CHECKBOX-0">
<lightning-primitive-cell-checkbox lightning-datatable_table="">
<span >
<input type="checkbox">
<label>
<span >
</span>
<span>Select Item 1</span>
</label>
</span>
</lightning-primitive-cell-checkbox>
</td>
<th label="Product Company">
<lightning-primitive-cell-factory label="Product Company">
<span>
<div>
<lightning-base-formatted-text>Company 1</lightning-base-formatted-text>
</div>
</span>
</lightning-primitive-cell-factory>
</th>
<td label="Product Name">
<lightning-primitive-cell-factory label="Product Name">
<span>
<div>
<lightning-base-formatted-text>Product type 1</lightning-base-formatted-text>
</div>
</span>
</lightning-primitive-cell-factory>
</td>
</tr>
<tr row-number="2">
<td value="0-SELECTABLE_CHECKBOX-0">
<lightning-primitive-cell-checkbox lightning-datatable_table="">
<span >
<input type="checkbox">
<label>
<span >
</span>
<span>Select Item 2</span>
</label>
</span>
</lightning-primitive-cell-checkbox>
</td>
<th label="Product Company">
<lightning-primitive-cell-factory label="Product Company">
<span>
<div>
<lightning-base-formatted-text>Company 2</lightning-base-formatted-text>
</div>
</span>
</lightning-primitive-cell-factory>
</th>
<td label="Product Name">
<lightning-primitive-cell-factory label="Product Name">
<span>
<div>
<lightning-base-formatted-text>Product type 2</lightning-base-formatted-text>
</div>
</span>
</lightning-primitive-cell-factory>
</td>
</tr>
</table>
My goal is to use Xpath to select a single unique checkbox input element in the table, but I can only use the Company and Product values listed in the table itself, so I cannot select by row number. How would I go about this?
CodePudding user response:
@Matt M, for python and Selenium, you can do as given below. You can replace the url given in the code. It will select the row based on company name provided in variable company
. Same can be done for the product name:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
s = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(options=chrome_options, service=s)
driver.get("http://127.0.0.1:5555/dropdown.html")
allRows = driver.find_elements(By.TAG_NAME, "tr")
company = "Company 2"
for row in allRows:
if company in row.text:
row.find_element(By.TAG_NAME, "input").click()
CodePudding user response:
To do that using xpath, you need to use the document.evaluate() method which supports xpath. You then need to form an xpath expression.
In this case it could be (among some other options)
//table//tr[.//.="Company 2"][.//.="Product type 1"]//input[@type="checkbox"]
which could be roughly translated into English as
in the table, find a
<tr>
which has, among its children, a text element equal to "Company 2" (or whatever) and another one equal to "Product type 1" (again, or whatever); once you find it, look for another<input>
child of that same<tr>
which has an attributetype
with an attribute value ofcheckbox
.
Now you let document.evaluate()
evaluate it, and once that element is found, have javascript toggle that element's checked
status.
All together:
xpath = '//table//tr[.//.="Company 2"][.//.="Product type 1"]//input[@type="checkbox"]';
target = document.evaluate(
xpath,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
);
target.singleNodeValue.checked = true;