pixelhead
pixelhead

Reputation: 59

Selenium | Unable to locate input element

No idea how to address this input text field element with selenium / Java (openjdk 11 2018-09-25).

I tried xpath, cssSelector etc. it never works. Its always "Unable to locate element".

<slot name="input">
   <input part="value" tabindex="0" aria-labelledby="vaadin-text-field-input-3">
</slot>

This did NOT work:

driver.findElement(By.xpath("//input[@aria-labelledby='vaadin-text-field-input-3']")).sendKeys("test");

Is there a solution for this?

UPDATE:

This thread solved partly my problem. The solution that worked for me can be found here link.

Upvotes: 0

Views: 3032

Answers (4)

cruisepandey
cruisepandey

Reputation: 29382

Xpath:

//div[@class='vaadin-text-field-container']//descendant::input[@part='value' and starts-with(@aria-labelledby, 'vaadin-text-field-input')]

Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.

Steps to check:

Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.

If this is unique //div[@class='vaadin-text-field-container']//descendant::input[@part='value' and starts-with(@aria-labelledby, 'vaadin-text-field-input')] then you need to check for the below conditions as well.

  1. Check if it's in any iframe/frame/frameset.

    Solution: switch to iframe/frame/frameset first and then interact with this web element.

  2. Check if it's in any shadow-root.

    Solution: Use driver.execute_script('return document.querySelector to have returned a web element and then operates accordingly.

  3. Make sure that the element is rendered properly before interacting with it. Put some hardcoded delay or Explicit wait and try again.

    Solution: time.sleep(5) or

    WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='vaadin-text-field-container']//descendant::input[@part='value' and starts-with(@aria-labelledby, 'vaadin-text-field-input')]"))).send_keys("test")

  4. If you have redirected to a new tab/ or new windows and you have not switched to that particular new tab/new window, otherwise you will likely get NoSuchElement exception.

    Solution: switch to the relevant window/tab first.

  5. If you have switched to an iframe and the new desired element is not in the same iframe context then first switch to default content and then interact with it.

    Solution: switch to default content and then switch to respective iframe.

You can start debugging from step1.

Update:

Solution specific to the problem:

Thread.sleep(2000);
WebElement inputButton = (WebElement) ((JavascriptExecutor)driver).executeScript("return document.querySelector('#TextFieldTitle').shadowRoot.querySelector('#vaadin-text-field-input-3 > slot:nth-child(2) > input')");
inputButton.sendKeys("test");

in the place of paste query selector here you will have to go to dev tools again in goog chrome by pressing F12, and then

  1. Go to that input box
  2. Do a right click
  3. Select copy
  4. Select copy JS path.
  5. Ctrl + v into notepad to see what you've got from the dev tool.

It'd be something like this:

document.querySelector("#vaadin-text-field-input-3 > slot:nth-child(2) > input")

replace this paste query selector here with the stuff that is wrapped inside ""

Upvotes: 1

catch32
catch32

Reputation: 18612

Looks like part of HTML looks like:

<div class="vaadin-text-field-container">
    <label part="label" id="vaadin-text-field-label-3"></label>
    <div part="input-field" id="vaadin-text-field-input-3">
        <slot name="prefix"></slot>
        <slot name="input">
            <input part="value" tabindex="0" aria-labelledby="vaadin-text-field-input-3">
        </slot>
    </div>
</div>

Much better is to build your XPATH locator from some id field:

//div[@id='vaadin-text-field-input-3']//input[contains(@aria-labelledby, 'vaadin-text-field-input')]"]

Also, as mentioned earlier have to check:

  • if it is unique for this page
  • if the input element is not dynamic

If you found solved that comment you could move to the code part and use the founded locator with WebDriver:

driver.findElement(
     By.xpath("//div[@id='vaadin-text-field-input-3']//input[contains(@aria-labelledby, 'vaadin-text-field-input-3')]"]"
)).sendKeys("test");

Also, keep in mind that you have to know that element is already loaded on a page. As suggested before you could use some explicit wait for your element.

Upvotes: 0

undetected Selenium
undetected Selenium

Reputation: 193328

To send a character sequence to the element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following locator strategies:

new WebDriverWait(driver, 20)
    .until(ExpectedConditions.elementToBeClickable(
          By.cssSelector("div.vaadin-text-field-container div[part=input-field][id^='vaadin-text-field-input'] slot[name='input'] > input[part='value'][aria-labelledby^='vaadin-text-field-input']")
    )).sendKeys("pixelhead");
new WebDriverWait(driver, 20)
   .until(ExpectedConditions.elementToBeClickable(
      By.xpath("//div[@class='vaadin-text-field-container']//div[@part='input-field' and starts-with(@id, 'vaadin-text-field-input')]//slot[@name='input']/input[@part='value' and starts-with(@aria-labelledby, 'vaadin-text-field-input')]")
   )).sendKeys("pixelhead");

Upvotes: 1

Anand Gautam
Anand Gautam

Reputation: 2101

Per the html provided, this works:

driver.find_element(By.XPATH, "//input[@part='value' and contains(@aria-labelledby, 'vaadin-text-field-input')]"]

x = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@part='value' and contains(@aria-labelledby, 'vaadin-text-field-input')]")))
x.send_keys('This is typed here by selenium')
print(f"the typed text in input box is: {x.get_attribute('value')}")

Output:

the typed text in input box is: This is typed here by selenium

Process finished with exit code 0

Upvotes: 0

Related Questions