从技术角度来看,Selenium 如何点击网页上的元素?

Posted

技术标签:

【中文标题】从技术角度来看,Selenium 如何点击网页上的元素?【英文标题】:From a technical perspective, how does Selenium click an element on a web page? 【发布时间】:2016-01-30 23:25:51 【问题描述】:

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


问题背景

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

这样做的主要影响是 Selenium 的大部分功能无法按预期工作。它无法像在 Firefox 和 Chrome 中那样“看到”Internet Explorer 中的 Shadow DOM。

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

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

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


问题

我正在尝试以简化的形式复制Actions.click(WebElement onElement) (source) 的功能(不遵循 Actions 类的 Builder 设计模式,并假设单击是鼠标左键并且没有其他键(CtrlShiftAlt)被按住)。

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

创建一个新的ClickAction (source)(稍后执行)。执行此操作包括在 Mouse 接口 (source) 的实例上调用“click()”... aaaa 我迷路了。我从generated JavaDoc 看到,这是由EventFiringMouse (source) 或htmlUnitMouse (source) 实现的,但我不确定哪个会实现。我做了一个假设(几乎没有根据)HtmlUnitMouse 会被使用,这让我在HTMLUnit code from Gargoyle Software 的兔子洞里走得更远...

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

任何指导将不胜感激:)


研究

我发现我认为 HTMLUnit 被 Chrome、Firefox 和 Internet Explorer 使用的假设是错误的。文档显示RemoteWebDriver (source) 是ChromeDriverFirefoxDriverInternetExplorerDriver 的子类。

【问题讨论】:

WebDriver 实现决定哪一个,有ChromeDriverFirefoxDriverInternetExplorerDriverHtmlUnitDriver,其他......根据底层浏览器,每个人的行为都不同。所以第一步是决定其中一个并深入挖掘。 您是否考虑过联系 Selenium 开发人员,并可能与他们合作以增强 Selenium 本身? @SiKing 我们已经考虑过(对于更大的问题)。它(即 Polyfills 问题)是几周前在 Selenium GitHub 上提出的一个问题,并被另一位发帖者承认,但最近没有任何活动。我们的时间和资源有限,鉴于这种情况,编写解决方法被认为是我们的最佳选择。 @AhmedAshour 我们需要在这三个 Web 浏览器中的每一个上进行测试。如上所述,我们已经提出了 Selenium 的一个问题,但是我们没有资源等待未知的时间长度来让外部团队解决这个问题。我很欣赏他们使用RemoteDriver 的澄清,但“只是向其他人提出错误并停止解决问题”对我们来说不是一个有用的解决方案。 @Eilidh 对不起,给你错误的链接,这里是正确的github.com/SeleniumHQ/selenium/blob/… 简而言之,闭包库是整个架构的每个底层,它提供了大部分原子操作,从获取属性来合成元素点击。这种实现和一些在 Selenium 中称为“原子”的额外逻辑(您可以从路径中看到)。是的,适用于所有浏览器。另一个问题是如何将其注入每个浏览器(每个浏览器都有自己的方式)。 【参考方案1】:

要点

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

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

一旦浏览器接收到请求,它将作为“本地事件”或综合执行操作。浏览器如何执行操作取决于浏览器的功能(可能还有一个标志选项)。

“本机”事件是操作系统级别的事件。

综合执行的操作是使用 JavaScript 执行的。使用“自动化原子”——从“原子”推断出来,它们是执行低级操作的小而简单的函数。


参考文献

RemoteWebDriverChromeDriverFirefoxDriverInternetExplorerDriverOperaDriverSafariDriver 的子类。 (reference)

与浏览器或 RemoteWebDriver 服务器通信的所有 WebDriver 实现都应使用通用有线协议。此有线协议通过 HTTP 使用 JSON 定义了一个 RESTful web service。 (reference)

在 WebDriver 中,通过直接模拟 JavaScript 事件(即合成事件)或让浏览器生成 JavaScript 事件(即本机事件)来提供高级用户交互。原生事件可以更好地模拟用户交互,而合成事件是独立于平台的 [...] 应尽可能使用原生事件。 (reference)

浏览器自动化原子是供 Selenium 实现使用的构建块。通过在整个代码库中使用相同的部分,而不是在多个地方重新实现所需的功能,该项目可以减少发现的错误数量,并可以简化添加新功能和驱动程序的过程。 (reference)


自动化原子

A summary of the available Automation Atoms The raw JavaScript code for the Automation Atoms - 如果有必要,这可以作为开发更简单的合成事件的有用起点。

【讨论】:

这里是点击代码的更新链接:github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/…【参考方案2】:

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

由于 InternetExplorerDriver 仅适用于 Windows,因此它尝试使用 所谓的“本机”或操作系统级事件来执行鼠标和键盘 浏览器中的操作。这与使用模拟 相同操作的 JavaScript 事件。

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

IE 驱动程序使用click() 处理这一场景 Automation Atom,它本质上设置了 .selected 属性 元素并在 JavaScript 中模拟 onChange 事件。

【讨论】:

以上是关于从技术角度来看,Selenium 如何点击网页上的元素?的主要内容,如果未能解决你的问题,请参考以下文章

web原理

如何使用 Selenium 从亚马逊上的自动建议中“点击”某些建议?

手动打开一个chrome网页,想用python+selenium操作这个网页上的控件怎么办

在 Windows 和 iOS 之间共享文件时,从技术角度来看,iCloud 驱动器是如何工作的?

从成本角度来看,在 MySQL 上使用 MSSQL 的理由 [关闭]

selenium2+python 如何把鼠标定位在网页中一个元素上,类似于hover那种