Java 如何在Selenium中在HTML5画布上执行鼠标滚轮滚动?
我正在研究GWT应用程序(类似于油漆)。在这里,我有一个HTML5画布,其中有一个功能,上下滚动鼠标滚轮将放大和缩小画布 我搜索了很多,但没有找到解决此问题的方法。以下是我们所做的:Java 如何在Selenium中在HTML5画布上执行鼠标滚轮滚动?,java,selenium,selenium-webdriver,html5-canvas,mousewheel,Java,Selenium,Selenium Webdriver,Html5 Canvas,Mousewheel,我正在研究GWT应用程序(类似于油漆)。在这里,我有一个HTML5画布,其中有一个功能,上下滚动鼠标滚轮将放大和缩小画布 我搜索了很多,但没有找到解决此问题的方法。以下是我们所做的: int PosX = 0; int PosY = 10; JavascriptExecutor executor = (JavascriptExecutor) getDriver(); String script = "document.getElementById('frontCanvas').scrollBy(
int PosX = 0;
int PosY = 10;
JavascriptExecutor executor = (JavascriptExecutor) getDriver();
String script = "document.getElementById('frontCanvas').scrollBy("
+ PosX + "," + PosY + ")";
executor.executeScript(script);
WebDriverWait wait = new WebDriverWait(getDriver(), 20);
wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(script));
现在,上面的代码适用于另一个Angular应用程序,我在其中上下滚动div元素(有一个滚动条),但它不适用于GWT应用程序中的画布(没有滚动条)
我正在使用Selenium 3.14.0并在Chrome浏览器上运行此代码。
有人可以建议如何解决此问题吗?这将使用JS在当前页面中滚动特定内容
JavascriptExecutor executor = (JavascriptExecutor) getDriver();
executor.executeScript("window.scrollBy(" + start + "," + end + ")");
否则,您可以滚动直到找到WebElement,例如:
WebElement x;
JavascriptExecutor executor = (JavascriptExecutor) getDriver();
getJs().executeScript("arguments[0].scrollIntoView();", x);
谢谢
HTML元素用于通过JavaScript动态绘制图形。元素只是图形的容器。您必须使用JavaScript来实际绘制图形。Canvas有几种用于绘制路径、框、圆、文本和添加图像的方法
一般来说,要上下滚动鼠标滚轮,我们可以选择该类。但是,据我们所知,这个API似乎并不那么可靠。在Firefox中,每次鼠标下压
,鼠标上压
,或鼠标点击
都发生在元素的中心。因此,上面的代码将生成一个鼠标移动事件(x,y),然后将鼠标移动事件移动到画布的中心,然后将鼠标下移
,鼠标向上移动
,然后单击画布中心的所有内容。对于按钮来说,这可能很好,但是对于画布来说,这是不可行的,因为您希望能够在特定位置悬停
,单击
,等等。Safari的情况更糟,它只生成一个异常,表明不支持鼠标移动事件。同时,铬也可以很好地工作
可供替代的
一种解决方法是使用该接口,使用JavaScript手动调度合成的鼠标事件
从@FlorentB.中翻出一页,要向上滚动鼠标滚轮和向下滚动,可以通过脚本注入将鼠标滚轮、鼠标移动和滚轮事件发射到顶部元素,并且可以使用以下解决方案:
- 代码块:
package demo;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Canvas {
static WebDriver driver;
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.addArguments("disable-infobars");
options.addArguments("--disable-extensions");
driver = new ChromeDriver(options);
driver.get("https://www.google.co.uk/maps");
WebElement elm = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#scene > div.widget-scene > canvas")));
// Mouse wheel UP or Zoom In
wheel_element(elm, -500, 0, 0);
System.out.println("Mouse wheel UP or Zoom In through Wheel achieved !!!");
// Mouse wheel DOWN or Zoom Out
wheel_element(elm, 120, 0, 0);
System.out.println("Mouse wheel DOWN or Zoom Out through Wheel achieved !!!");
System.out.println("Mouse Scroll through Wheel achieved !!!");
}
public static void wheel_element(WebElement element, int deltaY, int offsetX, int offsetY)
{
try{
String script = "var element = arguments[0];"
+"var deltaY = arguments[1];"
+"var box = element.getBoundingClientRect();"
+"var clientX = box.left + (arguments[2] || box.width / 2);"
+"var clientY = box.top + (arguments[3] || box.height / 2);"
+"var target = element.ownerDocument.elementFromPoint(clientX, clientY);"
+"for (var e = target; e; e = e.parentElement) {"
+"if (e === element) {"
+"target.dispatchEvent(new MouseEvent('mouseover', {view: window, bubbles: true, cancelable: true, clientX: clientX, clientY: clientY}));"
+"target.dispatchEvent(new MouseEvent('mousemove', {view: window, bubbles: true, cancelable: true, clientX: clientX, clientY: clientY}));"
+"target.dispatchEvent(new WheelEvent('wheel', {view: window, bubbles: true, cancelable: true, clientX: clientX, clientY: clientY, deltaY: deltaY}));"
+"return;"
+"}"
+"}";
WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].parentNode;", element);
((JavascriptExecutor) driver).executeScript(script, parent, deltaY, offsetX, offsetY);
}catch(WebDriverException e)
{
System.out.println("Exception caught in Catch block");
}
}
}
- 控制台输出:
Mouse wheel UP or Zoom In through Wheel achieved !!!
Mouse wheel DOWN or Zoom Out through Wheel achieved !!!
Mouse Scroll through Wheel achieved !!!
参考文献
您可以在以下内容中找到一些相关的详细讨论:
为什么要调用html元素上的scrollBy
事件,而不是直接在窗口上调用它?只有当canvas
元素的父元素具有固定的高度和宽度时,它才会起作用。@DipenShah直接调用窗口在我的情况下不起作用,那么我建议从父元素到父元素,找到宽度和高度小于canvas
元素本身的父元素。我想这是唯一能让它工作的方法。@DipenShah,我不确定这段代码是否能用于实现预期的目标。这只是为了演示我之前所说的,但是NVM。我尝试了这种方法,但在我正在工作的应用程序的画布上它没有任何作用。