so cal cheesehead so cal cheesehead - 5 months ago 60
Java Question

Selenium unable to locate element using xpath but firebug can

I have the following code to locate an element using a Xpath which using Firebug it works great. When I run my program I get the following exception:


Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"(//div[@class=\" x-ignore x-menu x-component \"]//div)/a[text()=\"ID\"]"}


If I take that exact xpath and stick in Firebug I can find my element no problem. Any ideas why Selenium can't find it?

Here's my code:

public static void displayColumn(String column) throws Exception {
String columnOptionsDropdownXpath = "(//div[@class=\"x-grid3-header\"]//span)[1]/../a";
String columnXpath = "(//div[@class=\"x-grid3-header\"]//span)[1]";
String columnsXpath = "(//div[@class=\" x-ignore x-menu x-component\"]//a)[3]";
String columnToDisplayXpath = "(//div[@class=\" x-ignore x-menu x-component \"]//div)/a[text()=\"" + column + "\"]";

// Because the 'column options' button doesn't appear until you hover over the column
WebElement col = null;
try {
col = driver.findElement(By.xpath(columnXpath));
} catch (NoSuchElementException e) {
System.out.println("Column not found - is it displayed?");
}

Actions builder = new Actions(driver);
builder.moveToElement(col).build().perform();
WebElement element = driver.findElement(By.xpath(columnOptionsDropdownXpath));
element.click();
Thread.sleep(500);

element = driver.findElement(By.xpath(columnsXpath));
builder.moveToElement(element).build().perform();
Thread.sleep(2000);
WebDriverWait wait = new WebDriverWait(driver, 10);
try {
System.out.println("in try statement");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(columnToDisplayXpath)));
} catch (TimeoutException e) {}

element = driver.findElement(By.xpath(columnToDisplayXpath));
element.click();
}

Answer

As mentioned in the comments, the slight difference between these two XPaths:

String columnsXpath = "(//div[@class=\" x-ignore x-menu x-component\"]//a)[3]";
String columnToDisplayXpath = "(//div[@class=\" x-ignore x-menu x-component \"]//div)/a[text()=\"" + column + "\"]";

besides the part at the end, is that the latter has a space after "component" and the former doesn't.

I suspect that the using normalize-space() and removing the leading and trailing spaces in the comparison values might help iron out inconsistencies in the spacing of the @class attribute value:

String columnsXpath = "(//div[normalize-space(@class) = \"x-ignore x-menu x-component\"]//a)[3]";
String columnToDisplayXpath = 
    "(//div[normalize-space(@class) = \"x-ignore x-menu x-component\"]//div)/a[text()=\""
    + column + "\"]";
Comments