Add ID and ClassName to Elements editor


#1

Any update on adding ID and ClassName to the Elements editor? I can manually define ID and ClassName variables in the page object file but since they do not show up in the Elements editor you cannot use the nice drag and drop features and thus have to copy existing methods and edit them with the new id.


#2

Hey there @jmsc7ran,

using ClassName or ByID selectors is actually not a good idea as the performance of these, compared to pure CSS selectors is generally lower. Moreover there is not really a need since you can easily express all of them with pure CSS plus stay open for adjustments in case you need to narrow down the selector. e.g you start out with .form but suddenly want to narrow it to .form.primary since a second got added.

Take a look at this topic for further info


#3

Hello vsoftic,
Thank you for the reply but I would like to give some supporting evidence on why you should include IDs in the editor. I have included a couple references and highlighted relevant sections from them.

[https://mestachs.wordpress.com/2012/08/13/selenium-best-practices/]

  • Preferred selector order : id => name => css => xpath
  • In practice, you will discover
    id and name are often the easiest and surest way.

[https://blog.mozilla.org/fxtesteng/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/]

  • IDs are king!
  • IDs are the safest locator option and should always be your first choice. By W3C standards, it should be unique in the page meaning you will never have a problem with finding more than one element matching the locator.

My thoughts:

  1. ID is the unique identifier for an element and it does not change if the DOM contents change. This makes IDs a very explicit and reliable way to locate elements on the page.
  2. Also, all browsers have highly efficient methods to get an object on the page using their ids. This makes id locators the fastest type of locator in Selenium.
  3. While I can manually add By.id variables and copy an existing method and modify it in the page object file, this is a pain and not very clean. Since my product team enforces unique IDs, that is the accepted method for locating elements in my company (as many other companies probably do).
  4. Even if Selocity does not support sending an ID to the editor, having the ability to work with IDs in the editor would be a nice addition. You might consider a survey of the Webtestit user base to see if that would be a welcome addition.
  5. Lastly, I love Webtestit and would like to see wider acceptance as I’m sure you would. If a company enforces the developers to use unique IDs and that is their preferred method of locating web elements; they may see that the editor does not support IDs and not even give Webtestit an evaluation.

Thank you for your consideration.


#4

Hey there @jmsc7ran,

thanks for the shared articles. Keep in mind though that these are from 2012 and 2013, which is kind of a century in the world of Browsers. I wasn’t also advocating you shouldn’t use IDs per se, although keep in mind that certain frameworks make use of dynamic ids, e.g ExtJS, ASP WebForms etc. There, IDs are definitely misleading since they are generated anew on every visit.

I was actually more referring to the used Locators By.Id vs By.cssSelector. Just as a comparison from a 2016 reply on SO these are the numbers:

  • By.cssSelector("#id") : (58ms + 818ms + 261ms + 51ms + 72ms) / 5 = ~252ms
  • By.id("id") - (820ms + 543ms + 112ms + 434ms + 738ms) / 5 = ~529ms

So the cssSelector locator is 2x faster while besides that allowing for easier narrowing in future.
Your proposal to check out what the community thinks is great and is exactly what we did. So far from two other mentions in those regards, after we explained the issue they’ve happily switched to the more performant By.cssSelector.

We are really trying hard to promote best practices for our users wherever we can and using By.Id, from a performance standpoint, is simply bad. Especially given that the difference is so minimal in merely adding a # in front of your selector and changing the locator.
But while I would disagree that Ids are King, the customer certainly is King :wink: So I’ll make sure we re-evaluate this story again internally.

Thanks for checking back with us and taking time for the response.


#5

Hi vsoftic,
Like a TV evangelist, “I have seen the light!”.

Now that I further researched your response, I realize I did not understand how cssSelector truly worked. I thought to find an ID, you HAD to use By.id but now I see cssSelector can find an id with [id='some ID']. Not only that, but I found I can find elements with cssSelector using other attributes which solves some problems I was having with oddly coded elements.

Thank you so much for taking the time to explain it clearly to me!


#6

Haha love the evangelists analogy :wink:

Yes, with By.cssSelector you essentially get all the power that one would have in the Browser and JavaScript using document.querySelector.

While we’re at it let me give you one more example of why these are so powerful. Let’s take a quick look at https://the-internet.herokuapp.com/tables

The Example 2 is a table with 6 cols and 4 rows. The use case would be:

I want the value of second table’s second column of the second row which should be is Frank.

A selector could look like #table2 tr:nth-of-type(2) > .first-name. So let’s inspect all the steps of the selctor in detail. #table2 selects an element with the id table2 (you don’t need an attribute like selector for what as the # is the shortcut). tr:nth-of-type(2) picks a tr - aka row - and exactly the 2nd occurence. The > sign indicates now the next thing needs to be a direct child. And the thing we’re looking for is an element with the css class first-name.

So this little example shows how flexible a css selector can be, moreover it shows how you can step by step build your selector based on an use case and follow along. Most of the times, css selectors created in this way, result in an sustainable and stable one as they have their origin in a natural thinking process.

And without saying it’s magical, but … it kinda is, it is pretty close to what Ranorex Selocity will come up for you by default tr:nth-of-type(2) > .first-name :wink:


#7

Good stuff:
In the same vane, I was able to get the 3rd column in the 2nd row with:

By.cssSelector("#searchList\:mySearchesTable_data tr:nth-of-type(2) td:nth-of-type(3)")

Awesome…the cssSelector training continues…:thinking:


#8

Since you mentioned training. Here’s a fun game which let’s you build css selectors to grab parts of a dinging table :slight_smile: https://flukeout.github.io/


closed #9