We can click on a webelement in 2 ways:
Using WebDriver click – element.click()
Using JavaScript click – ((JavascriptExecutor)driver).executeScript("arguments[0].click()", element);
When we click on a webelement using WebDriver, it checks for 2 conditions before clicking - The element must be visible; and it must have a height and width greater than 0.
If preconditions are not satisfied, the click is not performed and we get an exception.
But the JavaScript click method does not check these preconditions before clicking. The HTMLElement.click() method simulates a mouse click on an element. When click() is used with supported elements (such as an <input>), it fires the element’s click event.
So, JavaScript can click on a webelement which may not be actually visible to the user or be clickable by WebDriver API.
But we know - "Selenium-WebDriver makes direct calls to the browser using each browser's native support for automation." Meaning...WebDriver tries to mimic actual user behavior when working on browsers.
From Selenium 3 onwards, WebDriver APIs are designed to simulate actions similar to how a real user would perform actions on the GUI via the browser, and not use wrapped JS calls to execute different commands on the browser, like it happens via SeleniumRC.
All browsers now have their own drivers which implement the WebDriver API and Selenium communicates with these drivers via HTTP and these drivers communicate natively with the browser. So we can say that the ChromeDriver performs actions similar to a user using the chrome browser.
JavaScript bypasses this and goes to interact with the DOM of the page directly. This is not how a real user would use a browser.
This is also similar to the problem we had with v1 of Selenium where it used JavaScript to directly communicate with the browser [because SeleniumRC was just a form of wrapped JavaScript calls]
Also sometimes, use of JS methods may not trigger events which would have been otherwise triggered had we used WebDriver. For example, a subsequent onClick() event may not get triggered when a button is clicked via JS.
Hence, in order to simulate actual user behavior we should go for WebDriver and use JS sparingly and only when direct methods of WebDriver dont work.
This was precisely the problem with SeleniumRC.
SeleniumRC had 2 components - core and server. The core is basically a bunch of JavaScript code that is injected into the browsers to control/automate the behavior. Using JavaScript to control browsers caused issues, specially with IE as it has a different implementation/behavior with JavaScript. In a way, Selenium sends Selenese commands over to Se Core via JS Injections which in turn control the browser.
Also, there was problem with the same origin policy of browsers and to overcome this, the server component was used so that all the JavaScript code injection was directed via the server, so as to appear that its originating from the same host. This caused problems when there were popups, file uploads, etc, and this was relatively slower to run.
[To avoid 'Same Origin Policy' proxy injection method is used, in proxy injection mode the Selenium Server acts as a client configured HTTP proxy, which sits between the browser and application under test and then masks the AUT under a fictional URL]
Also, there were many overlapping and confusing methods implemented which made it difficult to use.
WebDriver is a cleaner and object oriented implementation, and it controls the browsers using their native methods for browser automation, and does not rely on JavaScript injection. It works at the OS/Browser level, and does not have to use JS to control the browser.
Also SeleniumRC did not support headless testing; there was no HtmlUnitDriver.
No comments:
Post a Comment