与目前接受的答案所暗示的相反,当涉及到让WebDriver执行单击和在JavaScript中执行单击之间的区别时,PhantomJS没有什么特定的。
不同之处
这两种方法之间的本质区别是所有浏览器通用的,可以非常简单地解释:
WebDriver:当WebDriver进行单击时,它会尽可能地模拟真实用户使用浏览器时发生的情况。假设您有一个元素A,它是一个显示“单击我”的按钮,而元素B是一个透明的元素,但其尺寸和设置使其完全覆盖A。然后,您告诉 WebDriver 单击 A。WebDriver 将模拟单击,以便 B 首先收到单击。为什么?因为 B 覆盖 A,如果用户尝试单击 A,则 B 将首先获取事件。A 最终是否会获得点击事件取决于 B 如何处理该事件。无论如何,在这种情况下,WebDriver的行为与真实用户尝试单击A时的行为相同。div
zIndex
JavaScript:现在,假设你使用JavaScript来做.这种单击方法不会重现当用户尝试单击 A 时实际发生的情况。JavaScript 将事件直接发送到 A,B 不会得到任何事件。A.click()
click
为什么 JavaScript 单击在 WebDriver 单击不起作用时起作用?
正如我上面提到的,WebDriver将尝试尽可能地模拟真实用户使用浏览器时发生的事情。事实是,DOM可以包含用户无法与之交互的元素,而WebDriver不允许您单击这些元素。除了我提到的重叠情况外,这还意味着无法单击不可见的元素。我在Stack Overflow问题中看到的一个常见情况是,有人试图与DOM中已经存在的GUI元素进行交互,但只有在操纵其他元素时才变得可见。这有时会发生在下拉菜单中:您必须首先单击下拉菜单以显示下拉列表的按钮,然后才能选择菜单项。如果有人尝试在菜单可见之前单击菜单项,WebDriver 将犹豫不决,并说无法操作该元素。如果这个人然后尝试使用JavaScript来做这件事,它将起作用,因为无论可见性如何,事件都直接传递到元素。
什么时候应该使用JavaScript进行点击?
如果你使用Selenium来测试一个应用程序,我对这个问题的回答是“几乎从不”。总的来说,你的Selenium测试应该重现用户对浏览器的处理方式。以下拉菜单为例:测试应单击首先显示下拉列表的按钮,然后单击菜单项。如果由于按钮不可见而导致 GUI 出现问题,或者按钮无法显示菜单项或类似内容,则测试将失败,并且您将检测到该 Bug。如果您使用JavaScript点击,您将无法通过自动测试来检测这些错误。
我说“几乎从不”,因为可能有例外,使用JavaScript是有意义的。不过,它们应该非常罕见。
如果您使用Selenium来抓取网站,那么尝试重现用户行为并不那么重要。因此,使用JavaScript绕过GUI并不是一个问题。