0

I have a web page which i am automating, I can click on any other elements using xpath or name or ID, but this gets little tricky when the element which I want to click is inside label. Here is the example,

<div class="dv-widget dv-deco-def dv-sz-med dv-map-sw">
<input name="l_maps" id="grp_perc" value="0" class="map_HD dv-radio-swr" type="radio">
<label for="grp_percentage" class="dv-radio-swl" onclick="">%</label>
<input name="l_maps" id="grp_count" value="1" class="map_HD dv-radio-swr" checked="" type="radio">
<label for="grp_multiply" class="dv-radio-swl" onclick="">*</label></div>

I need to click on the radio buton with the text % on it, I tried several option using xpath and CSS and ID but nothing seems to find that element under that label. I need help on this guys please. Thank you in advance.

JeffC
  • 22,180
  • 5
  • 32
  • 55
Rob
  • 150
  • 1
  • 4
  • 17
  • I tried option like self.driver.find_element_by_xpath("//*[@id='grp_perc']") but that did not help me earlier – Rob Mar 27 '18 at 16:19

2 Answers2

0

To click on the radio button with the text as % you can use either of the following lines of code :

  • Using preceding :

    driver.find_element_by_xpath("//label[@class='dv-radio-swl' and @for='grp_percentage']//preceding::input[1]").click()
    
  • Using preceding-sibling :

    driver.find_element_by_xpath("//label[@class='dv-radio-swl' and @for='grp_percentage']//preceding-sibling::input[1]").click()
    
  • Using ancestor :

    driver.find_element_by_xpath("//label[@class='dv-radio-swl' and @for='grp_percentage']//ancestor::input[1]").click()
    

Update

As per the first part of the xpath I have provided it correctly identifies the <label> element with text as %. See the snapshot :

label_xpath

Now, appending preceding makes no mistake to identify the previous <input> tag. See snapshot :

preceding_xpath

So in all means our xpath is correct. Possibly, you need to induce a waiter for the element to be clickable as follows :

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[@class='dv-radio-swl' and @for='grp_percentage']//preceding::input[1]"))).click()

If you are still unable to locate the element check the HTML if the element is within an <iFrame> tag and you will find a detailed discussion in How can I select a html element no matter what frame it is in in selenium?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
0

This is kind of a strange situation. Typically the for attribute of the LABEL matches the ID of the INPUT that it corresponds to, e.g.

<input id="name" ... >
<label for="name" ... >

But in this case it doesn't match. We can get around it pretty easily. You can search for the element that contains the % text using XPath and then find the preceding INPUT.

//label[.='%']/preceding-sibling::input

If you plan to use this elsewhere also, I would suggest that you put this into a function and pass in the LABEL text, e.g. % and feed that into the locator to click the matching INPUT.

JeffC
  • 22,180
  • 5
  • 32
  • 55