web-dev-qa-db-ja.com

SeleniumでHTML5キャンバス上でマウスホイールスクロールを実行する方法

私はGWTアプリケーション(ペイントと同様)に取り組んでいます。これには、HTML5 Canvasがあり、マウスホイールを上下にスクロールすると、キャンバスをズームインまたはズームアウトする機能があります。

私はたくさん検索しましたが、この問題を修正するための回避策は見つかりませんでした。これが何をしたかです:

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ブラウザでこのコードを実行します。この問題を修正するために何ができるかを誰かが提案できますか?

10
TheHungryCoder

HTML5キャンバス

HTML要素は、JavaScriptを介してその場でグラフィックを描画するために使用されます。要素はグラフィックのコンテナにすぎません。 JavaScriptを使用して実際にグラフィックスを描画する必要があります。 Canvasには、パス、ボックス、円、テキストを描画し、画像を追加するためのいくつかのメソッドがあります。

一般に、scrollマウスホイールupおよびdownActions Classを選択できます。しかし Selenium WebDriverを使用したHTML5 Canvasアプリケーションの自動テスト のように、このAPIはそれほど信頼できないようです。 Firefoxでは、すべてのmouse downmouse up、またはmouse clickは要素の中央で発生します。したがって、上記のコードはmouse moveイベントに提供された(xy)、次にmouse moveイベントをキャンバスの中央に移動し、次にmouse downmouse upclickはすべてキャンバスの中央にあります。これはボタンの場合は問題ないかもしれませんが、特定の場所でhoverclickなどを可能にしたいCanvasの場合は機能しません。 Safariでは状況がさらに悪化し、マウス移動イベントがサポートされていないことを示す例外が生成されるだけです。一方、Chromeは正常に動作します。

オルタナティブ

回避策は、JavaScriptを使用して合成マウスイベントを手動でディスパッチする JavascriptExecutor インターフェイスを使用することです。

@FlorentBの answer からリーフを取り出してscrollamousewheelpおよびdownmouseovermousemoveおよびwheeleventsスクリプトインジェクションを使用して一番上の要素に追加すると、次のソリューションを使用できます。

  • コードブロック:

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

これは、JSを使用して現在のページの特定の部分をスクロールします

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

それ以外の場合は、WebElementが見つかるまでスクロールできます。

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

おかげで、

1
Neagu V