【问题标题】:How to perform Mouse Wheel scrolling over HTML5 Canvas in Selenium?如何在 Selenium 中的 HTML5 Canvas 上执行鼠标滚轮滚动?
【发布时间】:2019-04-23 21:35:26
【问题描述】:

我正在开发一个 GWT 应用程序(类似于 Paint)。在此,我有一个 HTML5 画布,其中有一个功能是上下滚动鼠标滚轮将放大和缩小画布。

我进行了很多搜索,但没有找到解决此问题的解决方法。做了什么:

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 浏览器上运行此代码。 谁能建议可以做些什么来解决这个问题?

【问题讨论】:

  • 为什么要在 html 元素上调用 scrollBy 事件而不是直接在 window 上调用它?只有当canvas 元素的父元素具有固定的高度和宽度时,它才会起作用。
  • @DipenShah 直接调用窗口在我的情况下不起作用
  • 那我建议从父节点到父节点,找到宽度和高度小于canvas元素的父节点。我想这是让它发挥作用的唯一方法。
  • @DipenShah,我不确定这段代码是否可以用来实现预期的目标。
  • 只是为了演示我之前说的,但是NVM。

标签: java selenium selenium-webdriver html5-canvas mousewheel


【解决方案1】:

这将使用 JS 在当前页面中特定滚动

JavascriptExecutor executor = (JavascriptExecutor) getDriver();
executor.executeScript("window.scrollBy(" + start + "," + end + ")");

否则您可以滚动直到找到 WebElement 示例:

WebElement x;
JavascriptExecutor executor = (JavascriptExecutor) getDriver();
getJs().executeScript("arguments[0].scrollIntoView();", x);

谢谢,

【讨论】:

    【解决方案2】:

    HTML5 Canvas

    HTML 元素用于通过 JavaScript 动态绘制图形。元素只是图形的容器。您必须使用 JavaScript 来实际绘制图形。 Canvas 有多种方法用于绘制路径、框、圆、文本和添加图像。

    一般来说,对于scroll鼠标滚轮我们可以选择Actions类。但是根据Automated Testing of HTML5 Canvas Applications with Selenium WebDriver 看来,这个 API 并不那么可靠。在 Firefox 中,每个 mouse downmouse upmouse click 都出现在元素的中心。所以上面的代码产生一个mouse move事件到提供的(x,y),然后一个mouse move事件到画布的中心,然后一个@987654333 @、mouse upclick 都位于画布的中心。这对于按钮来说可能很好,但对于 Canvas 来说是行不通的,您希望能够在特定位置hoverclick 等。在 Safari 中情况更糟,它只是产生一个异常,表明不支持鼠标移动事件。与此同时,Chrome 运行良好。

    另类

    一种解决方法是使用 JavascriptExecutor 接口手动调度使用 JavaScript 的合成鼠标事件。

    从@FlorentB. 的answer 中取出一片叶子,滚动 鼠标滚轮 向上向下 strong>,您可以通过脚本注入将 mouseovermousemovewheel 事件 发送到顶部元素,然后您可以使用以下解决方案:

    • 代码块:

      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 !!!
      

    参考

    您可以在以下位置找到一些相关的详细讨论:

    【讨论】:

    • 我尝试了这种方法,但它在我正在工作的应用程序的画布中没有做任何事情。
    猜你喜欢
    • 2011-07-21
    • 2011-01-21
    • 2014-07-28
    • 1970-01-01
    • 2015-02-25
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多