从技术角度来看,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 设计模式,并假设单击是鼠标左键并且没有其他键(Ctrl、Shift、Alt)被按住)。
我想找到处理点击的核心代码(特别是在 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) 是ChromeDriver
、FirefoxDriver
和InternetExplorerDriver
的子类。
【问题讨论】:
WebDriver 实现决定哪一个,有ChromeDriver
、FirefoxDriver
、InternetExplorerDriver
、HtmlUnitDriver
,其他......根据底层浏览器,每个人的行为都不同。所以第一步是决定其中一个并深入挖掘。
您是否考虑过联系 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 执行的。使用“自动化原子”——从“原子”推断出来,它们是执行低级操作的小而简单的函数。
参考文献
RemoteWebDriver
是 ChromeDriver
、FirefoxDriver
、InternetExplorerDriver
、OperaDriver
和 SafariDriver
的子类。 (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 如何点击网页上的元素?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Selenium 从亚马逊上的自动建议中“点击”某些建议?
手动打开一个chrome网页,想用python+selenium操作这个网页上的控件怎么办
在 Windows 和 iOS 之间共享文件时,从技术角度来看,iCloud 驱动器是如何工作的?