Why does Selenium appends a back slash to the dot

2020-07-27 06:11发布

问题:

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!

回答1:

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')]")));