1

I want to get an element by ID with selenium in JAVA. The ID of the element in question so happens to have a period in it id="myprojectId0.123456789" when I try to find the element like so

WebElement projId = driver.findElement(By.id("mprojectId0.10724909303153396"));

I get this error in the console:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: #mprojectId0\.10724909303153396

For some reason the . character within the value of the ID attribute is being converted to \. and hence it cannot find the element. Please help and thanks in advance!

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
BlackMarker
  • 139
  • 12
  • 1
    Not sure why it is behaving like this until see the application.However you can try following xpath `driver.findElement(By.xpath("//*[starts-with(@id,'myprojectId0')]"))` – KunduK Sep 13 '19 at 20:03
  • `.` is a special character and should be escaped, `#mprojectId0\.10724909303153396`correct one. There's another reason why you're not able to locate the element. Check if the element inside `iframe` and try with explicit wait. – Sers Sep 13 '19 at 20:38

1 Answers1

2

Your observation is pretty much justified and as expected. As per the discussion in Official locator strategies for the webdriver By.id is translated by Selenium into it's equivalent By.cssSelector and as the . character is a special character, it is automatically escaped by a backslash i.e. \. Hence:

By.id("mprojectId0.10724909303153396")

gets translated into

By.cssSelector("#mprojectId0\.10724909303153396")

Solution

However the value of the id attribute i.e. mprojectId0.10724909303153396 looks dynamic to me and would change everytime the HTML DOM gets rendered. Accordingly you have to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following dynamic Locator Strategies:

  • cssSelector:

    WebElement projId = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[id^='mprojectId']")));
    
  • xpath:

    WebElement projId = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[starts-with(@id, 'mprojectId')]")));
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    You are correct. Having read the documentation, it makes sense to almost always use the `By.cssSelector` to select the element. Plus, I didn't realize that the ID I was trying to select was dynamically generated. I stuck to using the `By.xpath` – BlackMarker Sep 16 '19 at 15:27