1

Hi i am trying to locate element in selenium:

<button class="add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only" title="Add widget" role="button" aria-disabled="false">**
    <span class="ui-button-icon-primary ui-icon ui-icon-plus"></span>
    <span class="ui-button-text"></span>
</button>

I tried to use this xpath selection:

driver.findElement(By.xpath("//button[contains(@class,'add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only ui-state-hover')]/span[contains(@class,'ui-button-icon-primary')]")).click();

But it doesn't work and gives NoSuchElementException. Could you give me an advice how to build xpath to this element?

4 Answers 4

2

Actually will use Xpath, when we don't have a suitable or unique id/name attribute for the element which we wish to locate.

We can take xpath of an element in Three ways.

  • Absolute XPath (Not preferable, starts from main parent tag of element)
  • Relative XPath (Starts from parent tag of the current element,which you wish to locate.)
  • Same Level Xpath

    TagName[@property="value"]
    

For your developer code you can find XPath in above 3 ways.

  • Same Level XPath:

    button[@class="add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only"];
    
    (or)
    
    button[@title="Add widget"]
    
  • Relative XPath:

    Parent Tag name/button/class="add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only"
    

For Span Elements

  • Same Level XPath:

    button[@title="Add widget"]/span[1]
    button[@title="Add widget"]/span[2]
    
0
1

You have made one mistake here:

driver.findElement(By.xpath("//button[contains(@class,'add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only ui-state-hover')]/span[contains(@class,'ui-button-icon-primary')]")).click();
  • There is no class goes by the name "add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only ui-state-hover"

Please try this:

driver.findElement(By.xpath("//button[@role='button']/span")).click();

or

driver.findElement(By.xpath("//button[@title='Add widget']/span")).click();

I am not really sure which element you want to click? Your code would click on span, is that what you want? if you want to click on the button, please try the following:

driver.findElement(By.xpath("//button[@title='Add widget']")).click();
1

When creating selectors, usually the best approach is to use a minimal expression that uniquely identifies the target element. There may be several performance reasons behind it, but usually this also means the test case is easier to read and maintain.

Some CSS classes are dynamically assigned during run-time. In your case, this is the case with class ui-state-hover. This will be assigned to the button control only when mouse hovers over it (for example, when you click the element in browser to find its properties). As your test is looking for the element without first "hovering the mouse pointer over it", such a control is not found.

A basic fix would be to remove the ui-state-hover class from the button locator:

driver.findElement(By.xpath("//button[contains(@class,'add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only')]/span[contains(@class,'ui-button-icon-primary')]")).click();

However, if the class add-widget is unique to this button, it might be sufficient to use:

driver.findElement(By.xpath("//button[contains(@class,'add-widget')]/span[contains(@class,'ui-button-icon-primary')]")).click();
2
  • I found another solution using css selectors and action move to:
    – siutex
    Commented May 31, 2017 at 11:06
  • Actions bar = new Actions(driver); WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector( "#layout-center .ui-tabs-nav.ui-helper-reset.ui-helper-clearfix.ui-widget-header.ui-corner-all.ui-sortable"))); WebElement element2 = driver.findElement(By.cssSelector("#layout-center button.add-widget")); bar.moveToElement(element).moveToElement(element2).click(element2).build().perform();
    – siutex
    Commented May 31, 2017 at 11:07
-2

You can use

//button[@class='add-widget ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only'or @title='Add widget']
1
  • We can use both attribute through or operator Commented Jul 28, 2016 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.