I'm a beginner in automation testing. I'm trying to select a value from data list and I got an XPath like mentioned below:
XPath : html/body/div[2]/div[1]/div/div[1]
This is the HTML for the same :
<input id="portfolioName" class="form-control ng-valid ng-dirty ng-valid-parse ng-touched" ng-model="vm.portfolioName"
name="portfolioName[]" autocomplete="off"
list="portfolioNameList" ng-change="vm.onPortfolioNameChange()" onclick="this.value='';"
style="" type="text"/>
When I execute the test case, it displays No such element found
exception
How do I resolve this problem? I'm using Selenium and protractor.
4 Answers 4
Avoid the use of 'Absolute XPath' if possible in your coding.
If your element is having with class, ID, name & Type attributes then try to locate the element with the use of Relative XPath.
You can use-
XPath: //input[@id='portfolioName']
OR
XPath: //input[@id='portfolioName'][@type='text']
OR
Xpath=//input[@type='text' AND @name='portfolioName[]']
OR
Xpath=//input[contains(@id,'portfolioName')]
Best & easy way to locate Element with ID attribute is By ID:
driver.findElement(By.id("portfolioName"));
An absolute XPath should start with a slash /
:
'/html/body/div[2]/div[1]/div/div[1]'
.
It is advised to use relative XPath like: '//div[@id="portfolioName"]
'. For this to work, the id has to be unique for div tags.
However if the id is unique, you can better identify the object by id and not XPath:
driver.findElement(By.id("portfolioName"))
Say "No" to XPaths, to quote the Protractor style guide:
- It's the slowest and most brittle locator strategy of all
- Markup is very easily subject to change and therefore xpath locators require a lot of maintenance
- xpath expressions are unreadable and very hard to debug
There are better, faster and more readable ways to locate the element:
element(by.id("portfolioName"));
element(by.model("vm.portfolioName"));
If you are testing an Angular application with Protractor, in theory you should not experience timing issues since Protractor and Angular work together in sync - Angular signals Protractor when it is "ready". But, if you do experience timing issues, you can always add a wait - e.g. waiting for the element to be present:
var portfolioName = element(by.id("portfolioName"));
var EC = protractor.ExpectedConditions;
browser.wait(EC.presenceOf(portfolioName), 5000);
The input element has an id, better use this then the path from the html element to the input element. This path could change as the rendering is in a different state and or as the elements are injected in a different order each time.
Your Xpath could be: //*[@id="portfolioName"]
I would also research CSS selectors to use instead of Xpath as they are faster, easier to read and more flexible. Learn about all the other selectors and use XPath as a last resort.
Explore related questions
See similar questions with these tags.
right click on element -> copy -> copy xpath