0

I try to check (click) this checkbox using an XPath but all my attempts so far has failed, because they click on the link in the legend (Lorem ipsum)


rendered HTML


HTML source:


HTML source


<div class="input-outer checkbox">
   <div class="section-head sec-head2">
      <!---->
      <div class="pull-left">Tick this box</div>
      <!----><!---->
      <p aria-label="required" class="requiredAsteric">*</p>
   </div>
   <div class="input-validation">
      <div class="input-icon-outer">
         <!---->
         <!---->
         <!---->
         <!---->
         <input class="filled-in ng-untouched ng-pristine ng-invalid" type="checkbox" aria-label="Acceptera villkor" aria-required="true" aria-describedby="err_icon_prefix2_1" id="icon_prefix2_1"><!---->
         <label class="leadform-checkbox" tabindex="0" for="icon_prefix2_1">
            <div>
               <p>Lorem ipsum dolor sit amet, consectetur  <a href="https://www.google.com" target="_blank">adipiscing elit</a> adipiscing elit , sed do <a href="https://www.stackexchange.com" target="_blank">eiusmod tempor </a> incididunt ut labore et dolore magna aliqua.</p>
            </div>
         </label>
         <!---->
      </div>
   </div>
</div>

So far I have tried these three XPaths but none of them worked.

//label[@class='leadform-checkbox']/div";
//input[@aria-label='Tick this box']";
(//div[@class='input-icon-outer'])[3]";

If I understand the HTML correctly (which I probably don't), they don't use the checkbox functionality built in into HTML but have created a CSS-class that contains a graphical element that looks like a checkbox. Now when I send a click to the div that uses this style the click ends up on the textual content of the div, rather than checkbox, and clicks the link found there.

Have I understand things correctly? How do I fix this/direct the click to the square?

Edit: There are two other text fields in this "dialog". I have no problems accessing them with these two XPaths:

String xpText = "//input[@aria-label='text']";
String xpNumber = "//input[@aria-label='number']";

All three elements are in the same iframe. I perform several switches between the main content and different iframes before these steps.

The heading 2.2 is in the <div class="input-outer"> visible at the top of the screen shot of the HTML source above so I am pretty sure I am in the right frame/content. Besides, I could access the links in the text that belongs to this checkbox.

Included the whole dialog below to make it easier to get an overview.


The whole "dialog"

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    can you put the HTML in the question - a picture is hard to debug – Bravo Dec 13 '20 at 22:37
  • When you say "they don't use the checkbox functionality built in into HTML but have created a CSS-class that contains a graphical element that looks like a checkbox. " - they do, note just above the the centre of your screenshot you have ` – RichEdwards Dec 14 '20 at 11:00
  • @RichEdwards I have tried clicking that, but it just returns `org.openqa.selenium.ElementNotInteractableException: element not interactable`. –  Dec 14 '20 at 16:05
  • @Bravo Updated with source. –  Dec 14 '20 at 16:13
  • is there an `frame` or `iframe` present? - it looks like `//input[@aria-label="Acceptera villkor"]` would work – RichEdwards Dec 14 '20 at 16:19
  • The reasons elements are not found are 1) they're not there or wrong identifier) 2) they're not there yet and you need to use implicit or explicit waits 3) they're in frames or 4) they need to be scrolled into view (DOM updates when you scroll) .... Any of these sound like they're on the right path? - Happy to help, just need to know which you need – RichEdwards Dec 14 '20 at 16:24
  • @RichEdwards Yes and that was my first try but it failed. It something odd with this checkbox. –  Dec 15 '20 at 00:36
  • @RichEdwards 1) I can access the links in the text next to the checkbox. 2) See (1). 3) Yes, it is in an iframe, but again - I can access the links in the text next to the checkbox. 4) See (3). I appreciate your effort. Currently, I have resorted to a really ugly solution - send TAB, SPACE to `heading 2.2`, check for warning about the box being unchecked. If warning occurs, send another TAB, SPACE to `heading 2.2` :-( –  Dec 15 '20 at 00:39

3 Answers3

1

//input[@aria-label='Tick this box'] should do the trick.

Parolla
  • 408
  • 2
  • 6
  • Nope, already tried that (I forgot to include that in the question). Returns `org.openqa.selenium.ElementNotInteractableException: element not interactable`. –  Dec 14 '20 at 16:02
  • @hensti , try to define whether there are couple of these input nodes. or just try XPATH `(//input[@aria-label='Tick this box'])[2]` – Parolla Dec 14 '20 at 16:11
  • Only one, but when I send a click to it, it clicks the links in the text, not the checkbox:-( –  Dec 15 '20 at 00:42
  • Oddly enough, if I use the XPath from your comment above, but instead of sending a `click()` instead send `isSelected()` I get a correct response. Somehow `click` seems to prioritise text links ahead of checkboxes..? –  Dec 15 '20 at 01:16
  • @hensti this is weird :) maybe you should try to click it via JavaScriptExecutor? – Parolla Dec 15 '20 at 08:48
0

When you inspect the element make sure you are using the line in HTML which is highlights for the desired element. If it will not work make sure that there is no <iframe present on the page, also you can use parent/child relationship to identify the desired element. I would try to use: //div[@class='input-outer checkbox'] or //div[@class='section-head sec-head2']

tifoso
  • 58
  • 6
0

To click() on the checkbox you can use either of the following based Locator Strategies:

  • Using <label> tag attribute:

    driver.find_element_by_xpath("//label[@for='icon_prefix2_1']").click()
    
  • Using the <p> tag attribute:

    driver.find_element_by_xpath("//label[@class='leadform-checkbox'][.//p[contains(., 'Lorem ipsum dolor sit amet')]]//preceding::input[1]").click()
    
  • Using the <input> tag attributes:

    driver.find_element_by_xpath("//input[@class='filled-in ng-untouched ng-pristine ng-invalid' and @aria-label='Acceptera villkor']").click()
    

Ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following based Locator Strategies:

  • Using <label> tag attribute:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[@for='icon_prefix2_1']"))).click()
    
  • Using the <p> tag attribute:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[@class='leadform-checkbox'][.//p[contains(., 'Lorem ipsum dolor sit amet')]]//preceding::input[1]"))).click()
    
  • Using the <input> tag attribute:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='filled-in ng-untouched ng-pristine ng-invalid' and @aria-label='Acceptera villkor']"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352