What is the difference between the following location techniques?
element(by.id(\"id\"));
element(by.css(\"#id\"));
element(by.id("id"));
element(by.css("#id"));
element(by.xpath("//*[@id='id']"));
browser.executeScript("return document.getElementById('id');");
browser.executeScript("return document.querySelector('#id');");
I will give this a try. I will try to explain it until the point of Protractor
and WebdriverJS
. As I am not writing Selenium
or browser's drivers (E.g. Chromedriver
, Firefoxdriver
... etc...) which is the communication between browsers and Selenium
. For this I will use standard knowledge of browser's engine for this point. Therefore the answer, it will not 100% accurate but mostly.
For the first 3 methods:
element(by.id("id"));
element(by.css("#id"));
element(by.xpath("//*[@id='id']"));
These are all result with a single HTTP request to Selenium server. Which is:
'/session/:sessionId/element/:id/element'
With 2 parameters:
using
: type of :id
. Example: 'css select'
, 'id'
, 'xpath'
, 'link text'
... etc..value
: value of :id
. Example 'element-id'
, '.element-css > .child'
, //*[@id='id']
At this point Selenium
will answer the request accordingly to what is being requested through either of Chromedriver
, Firefoxdriver
... etc...
Under Webdriver find-element-strategy.js . As it is seem like methods are mapped with what browser providing by javascript document
properties. We got tag
, id
, css selector
, xpath
... etc.. which are matched with document.elementByTagName
, document.elementByID
, document.querySelecotr
, document.evaluate
...
Logically in the point of view of a coder I will say the resource should be reuse regardless how these drivers got written. For example quest request for id
it will most likely something like getElementById
got to be trigger at browser side through the communication driver.
=> SUMMARY So in the end we have:
css selector
equivalent of querySelector
id
equivalent of getElementById
xpath
equivalent of evaluate
For 2 last methods:
browser.executeScript("return document.querySelector('#id');");
browser.executeScript("return document.getElementById('id');");
These are all result with a single HTTP request to Selenium server. Which is:
'/session/:sessionId/execute'
With 2 parameters:
script
: javascript text ('string'
) or a function
args
: arguments is an array
Until this point it with be about how JS got injected into browser, as none of us can be sure the behavior (either using devtools
or inject into HTML). Let's just assume that it will be the same for all browser.
=> SUMMARY So in the end we will analyze :
querySelector
getElementById
element()
vs browser.executeScript()
:=> SUMMARY fast to slow
element()
browser.executeScript()
document.querySelector()
vs document.getElementById()
vs document.querySelector()
:Again each browser will result a slightly difference. But there are already some research about this. I will just use what community has been found.
CSS selector
being know that faster than xpath
(source)
document.querySelector()
> FASTER > document.evaluate()
(NOTE: xpath is not supported by IE, so selenium using its own xpath engine whenever you are using xpath on IE with protractor)
On jsperf.com we got this test that saying
document.getElementById()
> FASTER > document.querySelector()
=> SUMARY fast to slow
document.getElementById()
document.querySelector()
document.evaluate()
element(by.id("id"));
element(by.css("#id"));
element(by.xpath("//*[@id='id']"));
browser.executeScript("return document.getElementById('id');");
browser.executeScript("return document.querySelector('#id');");