I’m still relatively early in my web UI automation journey and for the locators I have used xpath exclusively so far. I had been reading some articles which referenced a preference for using css selectors over xpath so i’ve started diving a little further into them.
Can anyone more seasoned confirm, or deny, whether css is genuinely better and for what reasons? There’s some disadvantages it seems so unless you can cover everything with css selectors then I’m not not really sure why I would mix them up (and just stick to using xpath).
If the application is built with Angular you can’t rely on css locators because it can suddenly decide to rename them all during a build, and there are no “normal” identifiers like name or id to hook onto. I use relative xpaths for a lot of stuff - they start at the leaf node and work up the tree to the point where that snippet of path is unique and can only describe the leaf node. Relative xpaths are a little slower than css locators, but as you’re only going at the speed of the interface, it really doesn’t matter. And they seem Angular-safe so far.
Great point above which reflect what I thought might be the case.
I.e. The efficiency of the css might be marginally faster but if your limited by the speed the of ui then you might not even see the benefit.
In some cases I think the preference was literally down to the notation/syntax.
I.e. .classname vs //*[class=“class name”]
Are pretty much the same thing in terms of reliability, performance may differ, but I have yet to see tests that are slow because the specific RPC/IPC wire calls you make are the bottleneck.
As Jon pointed out unless you tell your developers to add additional tags to the elements if you are talking about a web framework like Angular, you will have pain. This will become apparent once you test picker lists and other dynamic elements. You will very quickly have to start building relative selectors. Basically when an xpath goes on to select a nearby or child element.
I love axes, for those elements where the tagged element is not actually the one you want, but it’s a parent of it or a sibling of it. You want to read up on how axes work. It’s possible to get a much better result using child:: or parent … to locate a nearby element in the tree, so worth learning about axes quite early on https://www.softwaretestinghelp.com/xpath-writing-cheat-sheet-tutorial-examples/
Cheers for the reply, I use axes quite a lot at the moment (at least how I understand them anyway) .
For example, on pages which are listing records in a grid and each row has an edit or delete and you want to find the edit/delete for your specific record - I find the text I want, then go up the document to find the element for the row as a whole and then come back down again from there for the edit button. (might not be the most efficient, I don’t know, but it works - I could check use of sibling instead but not sure if siblings have to be the same level)
Like a lot of us, it often feels like you are on your own @testerfromliverpool . web testing feels like the wild west because it’s often damned hard, not helped by the way cowboys breeze through.
I’m not currently working on a browser app, but on a mobile app, but the other half of the QA team do our web testing. And so recently I had to handle a case where we do open a real web page, and was so glad I could remember how to do it all still. But it sounds like you are actually on top of things. I cannot over emphasize this enough, when an xpath gives you trouble go over to the devs and ask them for help, try to make it their problem. Not getting help from your devs will burn you out.
I appreciate the words. I suppose back to the original question, I will stick to the xpath for now.
I have been working in a project where we decide to use only CSS and avoid XPATH.
XPATH has an advange: it’s easy to target to an element’s father than with CSS, but XPATH is more tied to the DOM, and we thought that a change in it would break the selector and the test.
The problem is always to get a good selector of the elements, and for that, it’s needed to get the developers collaboration.
Now I’m working with Cypress, and it has a plugin to work with XPATH (so, it works just with CSS by default); this is not a reason but I think that it’s a question to be made to a front developer (if we would like that the test could be updated for developers and not for QAs)
A good tactic is also to force your developer to write a few of the tests for a new feature. Just getting them to do your job will make them appreciate how terribly hard to test, their code has become. Testable code is maintainable code, and that is unfortunately the underlying driver of the entire CSS vs XPATH argument. This is not easy when your web app integrates with 3rd party apps or federates et al. You have no control. Moreover with web frameworks like Angular the CSS tagged element is often not the web element you want to control, so predicates are going to be used a lot if your app uses a modern framework, although there are ways to mitigate by having better debugging in your test framework to counter.
For me, it’s ultimately about getting better turnaround time on product changes. A CSS change due to a field moving to a different page is far easier to diagnose than a XPATH change when a field moved to another page.
With CSS can you navigate back up the html from the element you target? (i.e. the equivalent of ancestor or parent)? I tend to use this a fair bit in my xpaths (admittedly I shouldn’t need to, but there are some reasons for this I think - e.g. use of dev extreme for the ui).
I think that it’s not possible to get the parent with CSS, but it’s also a bad habit.
An example: there is a list/table with several elements, and the first cell contains the elements name, and the second cell the buttons to do something with it.
Just with CSS (but in Cypress there is a method to do it) you can’t target the button of a desired element.
But for that it’s great to implie the developers: if the row has a property to distinguish between the elements, there is no need to look up the parent.
I’ve had to do it for checkboxes with the aria animation style attached, because the animation ends up handling mouse-enter and actually covers/hides the control making it “unclickable” via selenium. They never warn you in the selenium tutorials and promo videos for all the cool test tools, that Typescript and all those “A” frameworks do this to you whenever your controls get fancied up. And then the tester ends up having to use xpath to “lift up a corner” and be able to click on something with an animation underneath the animation in a DIV sitting on top of it.
Also a problem for things like tapping on the password-unhide buttons with an eye and also for elipsis file browser fields which take one CSS element and break it into 2 web elements but are children of the CSS ID that wraps them for programming purposes in the framework. You have to be very wary of disabled controls in such settings too.
Hey, Sort of linked to this topic, do either of you guys know if there’s a way to mouse select and copy from the elements in Chrome tools? Say you had a long class name or attribute etc and you can’t to copy this from the html? You only seem to be able to copy the entire element.
I think it’s the entire line or nothing. If I try to highlight an attribute, the whole line moves.
Yep that’s what it looks like
Both are huge anti-patterns. By using either XPath or CSS Selector you are relying on details of implementation of the application and, as Jon Thompson pointed out, you are not safe from getting all of your tests broken should the framework of some of the libraries change. Moreover, those change relatively often excerpting a huge maintenance toll on you. The best way to build stable tests is to build them purely from end-user’s perspective, same way as you’d write a manual test case. Using, relative locations, names for icons, etc. This is literally exactly what https://testrigor.com makes easy to do. Try it out - it is free.