Good question, especially if people will read it and stop using XPath (I am not holding my breath).
Selenium best practices mentions order of preference: id > name > css > xpath
Mozilla explains why IDs
Saucelabs explains why CSS locators are preferred over XPath
slideshare compares locators (slide 23: CSS vs XPath)
CSS vs XPath - with benchmark
Choosing a good locator is very important to do carefully - it will define how reliable, readable, maintainable and durable your tests are going to be; how much dependent on the UI and design changes they are gonna be. Remember: maintaining end-to-end tests is, generally speaking, difficult and expensive (good read on the subject).
Here is a set of things ...
I think most answers are pretty good, but I would like to focus a bit on the higher level of these questions and not the details.
What makes a good Selenium locator?
Readability: Shorter is better, preferable with a clear unique name/id which describes this unique element on the page. Feel free to change the code like classes/names/id's to make the ...
For my money it is CSS Locators. Uses ID and/or class if there is one and uses position otherwise. Plus it is super easy to get Chrome to give you a CSS selector and test it in the console tab of DevTools via document.querySelector("yourCssSelectorHere") or doing a search on the Elements tab and pasting it in.
Most experienced Selenium users recommend CSS ...
Assume you want to take all the elements having class X but having no class Y. Then your code will look like:
For example for the below html:
<div class="x y">xy</div>
<div class="x y z">xyz</div>
<div class="x z">xz</div>
My main criteria is readability and maintainability.
Speed has never been as issue for me. There's other parts of the test frameworks I use that have much more significant speed issues.
The basic idea is always 'what will it take to uniquely identify the element' with two principles:
Don't over specify the page structure - this will make the selector ...
What makes a good selenium selector?
Given those quality attributes, in practice that translates into:
Favor css over xpath for readability
e.g. favor "form.new_user input.age" over "//form[@class='new_user']/input[@class='age']"
Favor id's on the last element of a selector
e.g. form.new_user input#last_name
What parameters would you consider to determine if a CSS selector is resistant to a change? What makes a reliable CSS locator? Some factors I would consider:
To start with, the basics are:
Locator should not include page layout structure
Don't base selector on the actual page text
Work within your existing framework(s)
Prefer css over xpath for ...
For ones who know xPath > would have pretty much the same meaning as / (slash) and " " (a whitespace) would mean the same as // (double slash).
Hence > takes direct children of an element, but " " takes all the nested elements.
In your example the first query would not necessarily locate the same element that the second would locate because the ...
I would say it is always a good idea from the standpoint of automated tests development efficiency. Unused attributes (you call them tags but they are rather the attributes) cannot be really considered as disadvantage since they have really no impact (in most of the cases) to the functionality.
The only disadvantage is the dev effort growing since adding ...
Putting test-specific code in production adds complexity to the production code and only helps QA. Instead, use it as an opportunity to make the production code better designed and more flexible for everyone.
In your example, the problem is that it's difficult and fragile to refer to the menu link. That is a problem which will ...
As an aside, although I will want to test the 'log in' capability too, is there a way to 'skip' this during testing, so that I can run the tests on all of the features of the app, without Protractor having to log in to the app every time to run the tests?
You have multiple ways of handling that, but using beforeAll() to provide setup for your it() tests ...
When there are multiple instances and there is no other way to distinguish them* you can refer to the instance index, i.e. 'which one'.
Note: 0 based index
You can see these in chrome tools, e.g.
css - $('a.instanceLink:...
Try this xpath
//*[contains(@class,'btn btn-primary btn-lg btn-block pink button') and contains(@tabindex,'4')]
The xpath basically means : any element that has class attribute containing 'btn btn-primary btn-lg btn-block pink button' and a tabindex attribute containing 4.
You should try to read a little about how to write custom xpaths as addons like ...
In XPath there are a couple of ways you could try this.
Match by text (can be partial text too)
Match by tag (if that helps isolate the label from other labels)
Match by partial tag value
Note the brackets surrounding the selectors ...
can you please try the options below:
By css selector:
Any one expression above should locate this element, please tell me if it still ...
If your edit class is unique on the page, then you can do .edit If you need to be a bit more specific, you could do more along the lines of .active.editing input.edit
The point is, theres no "right" answer here, there are often many different css selectors you can build that can point to the same element. You want to find the balance between being short, ...
No, a tag name is what you find in brackets:
It is a shortcut for the CSS selector tagName
Name, ID and class are all attributes of an element, they are simply shorthand for specific CSS selectors you could use. However, with this I don't mean they are executed like this behind the scenes (see Question 2 below).
Possibly the largest difference, in automation terms, is how fixed and brittle the locators are.
In the first example - the one with the >'s they effective mean that there must a div, with a div immediately within it, with a span immediately within that (ie no intermediary spans or div or table stuff) with a h1 immediately within that. In these contexts ...
It's Pretty easy. Look at your XPath expression and the Syntax error:
You have added unwanted bracket "()" in your XPath.
Your XPath should be:
@FindBy (how=How.XPATH, using= "//*[contains(text(), 'Hello,Nichole')]")
It looks live you've answered your own question
but the DOM says that element is
<a href="https://www.ebay.com/" ..../>
So update your code to reflect this different href exactly
The HTML you show has no ID (it's not the href that has a # btw, that's different).
will not work based on what you posted.
You could use:
Css is always my first go to for readability:
or by Class:
or by XPath
Explaining a bit more on how you can make your selector robust
If this is the selector you use
.content > table > tbody > tr:nth-child(2) > td.cell > input#email
And the input is moved out of table or even moved a cell, the selector breaks
But if the selector was
Then it would work even if ...
HTML id is not the same as HTML name. It's common to have fields where the name and the id are different:
<input id="user_name" name="inputName">
If you change your code to find the fields to element(by.name('inputName')); and element(by.name('inputPass')); it should find them.
The way you handle common routines like logging on is to use something ...
For all three parts of your question, I would suggest to apply one of the following approach (considering only web application, as mentioned in question itself):
First and the most naive approach is to use the recording feature. What I have read and understood is that record and playback feature provided by tools is only used for the purpose of Demo and ...
Any WebDriver will use Json Wire Protocol to interact with the browser. The protocol defines 5 locator strategies:
link text selector,
partial link text selector,
w3 Webdriver locator strategies
As you can see there is no "Id". By.Id is sugar syntax added by Selenium and other WebDriver implementations. Under the hood it ...
There are a lot of guidelines that will help you in choosing good, reliable, reusable, maintainable selectors. Simply inspecting an element and copying its xpath is one of the worst approaches.
When selecting an element:
Don't overspecify thus 'hard-coding' to the current layout and presentation
Don't underspecify wuth selectors that aren't unique or ...
If the class name is unique in the page then you can use the class name.
Keep in mind that the class name might not select the selector you need if there are multiple elements with the same class.
As an alternative check if you have other unique attributes for which you have a method or use a css/Xpath selector.
If you don't have any other attributes i ...
I currently work on a solution for exactly this problem (well, more the Problem of not existing identifiers but unknown ID´s are as good as non existing).
The idea is to use Seleniums getCurrentURL() method to get the source code, use a HTML parser library like JSoup to split it into nodes and add an dummy class signed with a trigonometric identity ...