Categories
css-selectors python python-3.x selenium selenium-webdriver

Of the many findElement(s)/By functions in Selenium, when would you use one over the other?

1

Selenium includes findElement functions, like so…

.find_element_by_

id
link_text
partial_link_text
name
class_name
tag_name
css_selector
xpath

It’s apparent that some are limited by design due to how the HTML page was created, such as id, link_text, name, tag_name, as not all tags may contain an id, link_text, etc… However, the css_selector and xpath can do pretty much everything these can do, and then some, but seem to be limited on what they can interact with. For example, some buttons might not be able to get clicked with the xpath, but can get clicked by css_selector.

So i’m wondering, when would one want to use one over the other(specifically xpath or css_selector)?

Are the other functions(id, link_text, etc), pretty much not useful, since (at least) I find that xpath/css_selector can do it as well?

Are there any benefits to using, lets say, link_text, over xpath/css_selector?

9

  • I use the function whichever gives me unique locator for the element! You might want to take a look at this page – elementalselenium.com/tips/32-xpath-vs-css, gives you performance stats.

    Jan 2, 2018 at 0:29

  • This discussion might be relevant: What makes a good selenium locator?.

    – alecxe

    Jan 2, 2018 at 0:41

  • 1

    I pretty much only use xpaths if I need to find something by text, or if the only way to find the element I want is to find another element, traverse back up the dom tree to some shared element, and then back down to the element I want. In my experience css selectors end up being cleaner and easier to read. You’ll find people arguing that xpaths are also slower, but in practice you’ll probably not notice a difference.

    Jan 2, 2018 at 3:23

  • 1

    @Matt Yes, mostly they are unique. If I see id, I use findelementbyid; if that’s missing, I use xpath/CSS selector. I do however have trust issues with findelementbyclass, as class names can be used in multiple places. I don’t worry about performance in the beginning, will chose the easy path. If performance is bad, only then I think about optimization. Hope it helps!

    Jan 2, 2018 at 11:38

  • 1

    @MattI let’s say you have a bunch of similar looking rows that all have some button in it you want to click. There is no way to directly uniquely get the button you want because all the rows have similar buttons with similar attributes. However, there is some other element in the row that is unique. So I could get that element, traverse back up the dom tree to get the row that contains it, and back down to get the button using xpath.

    Jan 2, 2018 at 17:43

6

This question have been asked and answered in numerous forums in different formats. Considering them all if we prioritize the locators the list would be as follows :

  • id: Select element with the specified id attribute.
  • name: Select first element with the specified name attribute.
  • link_text: Select link (anchor tag) element which contains text matching the specified LinkText.
  • partial_link_text: Select link (anchor tag) element which contains text matching the specified PartialLinkText.
  • tag_name: Locate Element using a Tag Name.
  • class_name: Locate Element using a ClassName.
  • css_selector: Select the element using CssSelectors.
  • xpath: Locate an element using an XPath expression.

So the question now is Whats New?

The answer is Selenium have evolved a lot recently. WebDriver is now a W3C Recommendation Candidate. Things within Selenium are changing pretty fast. It’s no more only about choosing the locator. We need to use a locator which will :

  • Uniquely identify an element.
  • The performance of the locator must be optimized.

Keeping these two factors in mind, the best strategy would be to Mock the DOM. The W3C Recommendation Candidate does mentions the list of the locators as per the below :

Selenium_Locators

So the verdict is clear and concise.

4

  • 1

    Obviously you have not read my question correctly. I know what these functions do, but i’m wondering why one would choose one over the other. Would there be a certain instance where xpaths would be more beneficial to use than css_selector, and vice versa.

    – Matt I

    Jan 2, 2018 at 9:16

  • 1

    Definitely you haven’t read the full verbatim of my Answer else you wouldn’t have missed the line where I mentioned The performance of the locator must be optimized.

    Jan 2, 2018 at 9:19

  • 1

    I did read it, but that line doesn’t specify anything. All you did was post what each tag does and some info that barely gets into what i’m looking for. How about this. When you go to a web page and inspect the HTML doc, when would you want to use xpath over css_selector, or vice versa? Is one more stable than the other, in terms of clicking the elements that I so desire to click on?

    – Matt I

    Jan 2, 2018 at 9:26

  • 2

    Stability depends on how effectively you write the automation code which I have detailed out in my Answer. To achieve the optimum performance I did provide you the sequential options starting with css and ending up with xpath from the W3C recommendation. However css and xpath are susceptible to DOM changes. Let me know if that Answers your Question.

    Jan 2, 2018 at 9:38

4

In my experience CSS is the preferable selector because it can be concise, is well documented and web developers are likely to have more experience and exposure to it.

id, name, tag_name and class_name can all be easily reproduced with simple CSS so I would avoid explicitly using those.

e.g.

id ; #my_id

name; [name=”my_name”]

tag_name; my_tag

class_name; .my_class

The use of XPath is often much maligned; labeled as slow and unstable. However I disagree with this view point.

When I interview people I cringe when they say they avoid Xpath because it is slow and brittle. The speed is no longer a concern, and xpath is only as brittle as the person who wrote it. However, I prefer the syntax of CSS Selectors so that is why I would choose over XPath for the majority of use cases.

There are 3 scenarios in which XPath is the better choice;

  • Multiple CSS Selectors may be replaced with one XPath query (e.g find element then iterate through sub elements can be performed in one xpath)

  • XPath can select based on Text where as CSS Selector cannot

  • XPath allows you walk up the DOM Tree which can be really useful if you can only identify a control by its child

I would always avoid selecting by text if possible, but if I had to, I would prefer to use XPath over the built in Link Text and Partial Link Text methods because the Xpath query woudl allow me to be more expressive and allow me to select more than just anchor tags.

Finally, once gotcha when using XPath is that “class” is treated as a literal string rather than an array of class names as supported in CSS selectors;

HTML: <div class="ab cd">

CSS matches: div.ab
CSS matches: div.cd
CSS matches: div.cd.ab
CSS matches: div.ab.cd

XPath matches: //div[@class="ab cd"]
XPath matches: //div[contains(@class, "ab")]
XPath matches: //div[contains(@class, "cd")]
XPath matches: //div[contains(@class, "ab") and contains(@class, "cd")]

XPath DOES NOT match: //div[@class="cd"]
XPath DOES NOT match: //div[@class="ab"]
XPath DOES NOT match: //div[@class="cd ab"]

4

  • Hmm, this was a very interesting read. I appreciate the info! When you say that xpath is only as brittle as the person who wrote it, how would I know if i’m using the correct path or not(assuming this is the weak point)?

    – Matt I

    Jan 5, 2018 at 3:06

  • 1

    There is no “correct path” for xpath, but that is true for CSS Selectors too. As an example take this page and your signature image. The following XPATH would work; //body/div[3]/div[1]/div[1]/div[1]/div[2]/div[1]/table/tbody/tr[1]/td[2]/div[1]/table[1]/tbody/tr/td[2]/div[1]/div[2]/a/div/img It would find your image everytime BUT if there was a small change in the HTML layout, it could easily break. I would call this a brittle XPATH. It is important to appreciate that I could just as easily write this in CSS just as bad!

    Jan 5, 2018 at 12:03

  • 1

    A better xpath could be ‘//div[contains(@class, “question”)]//a[@href=”/users/6402048/matt-i”]//img’. This will more resilient to structural changes. NB. In this case I would probably use CSS as it could be clearer; ‘.question a[href=”/users/6402048/matt-i”] >img’ However, to create the Xpath (or indeed CSS selctor) you need to understand the AUT and what your are trying to test

    Jan 5, 2018 at 12:06

  • @MattI Feel free to mark this as an answer if you think it addresses your question

    Mar 29, 2018 at 17:42