从技术角度来说,Selenium 是如何点击网页中的元素的?

From a technical perspective, how does Selenium click an element on a web page?

提供上下文以防有人知道解决更大问题的替代方法。


问题背景

我带头为使用 Web 组件的 Web 应用程序开发测试自动化框架。这在 Internet Explorer 中测试时出现了问题,因为 Internet Explorer 本身不支持 Web Components;相反,polyfill 用于提供此功能。

对此的主要影响是 Selenium 的大部分功能无法按预期工作。它不能像在 Firefox 和 Chrome 中那样在 Internet Explorer 中 'see' Shadow DOM。

另一种方法是编写一个测试框架,它提供了一种通过 JavaScript 访问元素的替代机制——这允许通过 polyfill 定位元素。

我们当前的实现检查正在使用的 WebDriver,并使用方法的原始 Selenium 实现(在 Chrome 或 Firefox 的情况下),或者我们自己的替代实现(在Internet Explorer 的情况)。

这意味着我们希望我们的实现在其核心、浏览器交互级别上尽可能接近 Selenium 的实现。


问题

我正在尝试以简化形式复制 Actions.click(WebElement onElement) (source) 的功能(不遵循 Actions class 的构建器设计模式,并假设点击是使用鼠标左键而不是其他键(CtrlShiftAlt) 被按住)。

我想找到处理点击的核心代码(特别是在 Chrome、Firefox 和 Internet Explorer 中),这样我就可以尽可能地复制它,但是我发现自己迷路了在 classes 和接口的深坑中...

一个新的 ClickAction (source) is created (to later be performed). Performing this includes a 'click()' call on an instance of the Mouse interface (source) ... aaaaand I'm lost. I see from generated JavaDoc that this is implemented by either EventFiringMouse (source) or HtmlUnitMouse (source), but I'm not sure which one will be implemented. I made an assumption (with little basis) that HtmlUnitMouse would be used, which has led me further down the rabbit hole looking at HTMLUnit code from Gargoyle Software...

简而言之,我完全迷路了。

任何指导将不胜感激:)


研究

wiki for the Selenium IE Driver 声明它使用本机事件而不是 JavaScript 事件与浏览器交互。

As the InternetExplorerDriver is Windows-only, it attempts to use so-called "native", or OS-level events to perform mouse and keyboard operations in the browser. This is in contrast to using simulated JavaScript events for the same operations.

除了单击 <option> 个元素,它使用 JavaScript。

The IE driver handles this one scenario by using the click() Automation Atom, which essentially sets the .selected property of the element and simulates the onChange event in JavaScript.

要点

Chrome、Firefox 和 Internet Explorer 的驱动程序都是 RemoteWebDrivers

这意味着 Selenium 执行的任何操作都会通过 HttpRequest 发送到浏览器 (WebDriver)。

一旦浏览器收到请求,它将以 "native event" 或综合的方式执行操作。浏览器如何执行操作取决于浏览器的功能(以及可能的标志选项)。

"Native"事件为OS级事件。

综合执行的动作使用JavaScript执行。 "Automation Atoms" 被使用 - 正如从 'atom' 推断的那样,它们是执行低级操作的小而简单的函数。


参考文献

  • RemoteWebDriverChromeDriverFirefoxDriverInternetExplorerDriverOperaDriverSafariDriver 的子类。 (reference)

  • All implementations of WebDriver that communicate with the browser, or a RemoteWebDriver server shall use a common wire protocol. This wire protocol defines a RESTful web service using JSON over HTTP. (reference)

  • In WebDriver advanced user interactions are provided by either simulating the JavaScript events directly (i.e. synthetic events) or by letting the browser generate the JavaScript events (i.e. native events). Native events simulate the user interactions better whereas synthetic events are platform independent [...] Native events should be used whenever possible. (reference)

  • Browser Automation Atoms are building blocks intended to be used by Selenium implementations. By using the same pieces throughout the codebase, rather than reimplementing required functionality in multiple places, the project can reduce the number of bugs found, and can simplify the process of adding new functionality and drivers. (reference)


自动化原子