是的,可以自动滚动浏览器,使我们与之交互的任何元素都在窗口中居中。我在下面有一个工作示例,使用 selenium-webdriver-2.41.0 和 Firefox 28 在 ruby 中编写和测试。
完全披露:您可能需要稍微编辑部分代码才能使其正常工作。解释如下。
Selenium::WebDriver::Mouse.class_eval do
# Since automatic centering of elements can be time-expensive, we disable
# this behavior by default and allow it to be enabled as-needed.
self.class_variable_set(:@@keep_elements_centered, false)
def self.keep_elements_centered=(enable)
self.class_variable_set(:@@keep_elements_centered, enable)
end
def self.keep_elements_centered
self.class_variable_get(:@@keep_elements_centered)
end
# Uses javascript to attempt to scroll the desired element as close to the
# center of the window as possible. Does nothing if the element is already
# more-or-less centered.
def scroll_to_center(element)
element_scrolled_center_x = element.location_once_scrolled_into_view.x + element.size.width / 2
element_scrolled_center_y = element.location_once_scrolled_into_view.y + element.size.height / 2
window_pos = @bridge.getWindowPosition
window_size = @bridge.getWindowSize
window_center_x = window_pos[:x] + window_size[:width] / 2
window_center_y = window_pos[:y] + window_size[:height] / 2
scroll_x = element_scrolled_center_x - window_center_x
scroll_y = element_scrolled_center_y - window_center_y
return if scroll_x.abs < window_size[:width] / 4 && scroll_y.abs < window_size[:height] / 4
@bridge.executeScript("window.scrollBy(#{scroll_x}, #{scroll_y})", "");
sleep(0.5)
end
# Create a new reference to the existing function so we can re-use it.
alias_method :base_move_to, :move_to
# After Selenium does its own mouse motion and scrolling, do ours.
def move_to(element, right_by = nil, down_by = nil)
base_move_to(element, right_by, down_by)
scroll_to_center(element) if self.class.keep_elements_centered
end
end
推荐用法:
在元素通常不在屏幕的任何代码段的开头启用自动居中,然后禁用它。
注意:此代码似乎不适用于链接操作。示例:
driver.action.move_to(element).click.perform
滚动修复似乎没有更新click 位置。在上面的例子中,它会点击元素的预滚动位置,从而产生误点击。
为什么是move_to?
我选择move_to 是因为大多数基于鼠标的操作都会使用它,并且 Selenium 现有的“滚动到视图”行为发生在此步骤中。这个特定的补丁不应该适用于在某种程度上不调用move_to 的任何鼠标交互,我也不希望它适用于任何键盘交互,但理论上,如果你包装正确,类似的方法应该有效功能。
为什么是sleep?
我实际上不确定为什么在通过executeScript 滚动后需要sleep 命令。通过我的特定设置,我可以删除 sleep 命令并且它仍然有效。 Similar examples 来自 other developers 的网络包括 sleep 命令,延迟范围为 0.1 到 3 秒。作为一个疯狂的猜测,我会说这是出于交叉兼容性的原因。
如果我不想进行猴子补丁怎么办?
正如您所建议的,理想的解决方案是更改 Selenium 的“滚动到视图”行为,但我相信这种行为是由 selenium-webdriver gem 之外的代码控制的。在线索变冷之前,我一直追踪代码到Bridge。
对于猴子补丁厌恶,scroll_to_center 方法作为一个独立的方法可以很好地工作,只需进行一些替换,其中driver 是您的Selenium::WebDriver::Driver 实例:
-
driver.manage.window.position 而不是
@bridge.getWindowPosition
-
driver.manage.window.size 而不是
@bridge.getWindowSize
-
driver.execute_script 而不是
@bridge.executeScript