Seleniumでビューに要素をスクロール


208

Selenium 1.xまたは2.xのいずれかに、ブラウザーウィンドウをスクロールして、XPathによって識別される特定の要素がブラウザーのビューに入るようにする方法はありますか?Seleniumにはfocusメソッドがありますが、FireFoxでビューを物理的にスクロールするようには見えません。これを行う方法について誰かが何か提案はありますか?

これが必要な理由は、ページ上の要素のクリックをテストするためです。残念ながら、要素が表示されていない限り、イベントは機能しないようです。要素がクリックされたときに起動するコードを制御できないため、デバッグも変更もできません。そのため、最も簡単な解決策は、アイテムをスクロールして表示することです。


他に何もうまくいかない場合は、このハッキーなものを試すことができます。stackoverflow.com/ a / 53771434/7093031
YB Cause

回答:


215

スクロールに関して多くのことを試しましたが、以下のコードはより良い結果を提供しました。

要素が表示されるまでスクロールします。

WebElement element = driver.findElement(By.id("id_of_element"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
Thread.sleep(500); 

//do anything you want with the element

6
これは、position: fixedページ上に要素がある可能性があり、Seleniumがクリックしたい要素を覆い隠してしまう場合の、きちんとしたソリューションです。多くの場合、これらの固定要素は下部に配置されるため、設定scrollIntoView(true)によりビューポートの上部にうまく移動します。
Mandible79 2014年

3
最新バージョンのセレン(2.53)に基づいて、これは現在、優れたヘルパーソリューションです。Seleniumは常に要素をスクロールして表示するわけではないので、これは間違いなく便利です。
Zoidberg 2016

20
スクロール先のオブジェクトが現在の場所の下にある場合、またはスクロール先のオブジェクトが現在の場所の上trueにあるscrollIntoView場合は、に渡しfalseます。それを理解するのに苦労しました。
ビッグマネー

2
なぜスレッドスリープが必要なのですか?executeScriptは同期的である必要があります
riccardo.tasso 2018

1
@ riccardo.tasso不明なターゲットアプリを処理するためにスリープが実装されている可能性があります。動的スクロール、またはスクロール後にページの次のビットをロードする単一ページのアプリがある場合。経験から言えば、自動化されたアクションがJavascriptが完了するよりも速く発生し、不完全なデータモデルが渡されたため、Seleniumは私の会社のサイトを頻繁に破壊しました。一部の場所ではそれをバグと見なす可能性がありますが、「人間がそのようなシナリオを呼び出すことはできないため、実際のバグではありません」と言われました。C'est la vie。
Solonotix

157

org.openqa.selenium.interactions.Actionsクラスを使用して要素に移動できます。

Java:

WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();

Python:

from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(driver.sl.find_element_by_id('my-id')).perform()

7
WebElementがビューポートにない場合、これは機能しますか?
virusrocks 2015年

9
@Dominik:Seleniumはどのようにして画面の外にある要素にマウスを移動しますか?明らかに、最初に要素をスクロールして表示し、次にマウスをその要素に移動する必要があります。私はそれをテストしました。このコードはFirefox Webdriver 2.48で機能しますが、バグがあります。ページにiframeがある場合、element.LocationOnScreenOnceScrolledIntoViewが正しくスクロールしている間、iframeでスクロールが正しく機能しません。(ドキュメントには、このコマンドは場所のみを返すと書かれていますが、スクロールもします!)
Elmue

8
seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/…のドキュメントに、 「マウスを要素の中央に移動します。要素はスクロールして表示され、その場所はgetBoundingClientRect。」
George Pantazes

5
上記のコードは「公式な方法」ですJava Seleniumは要素をビューポートにスクロールすることを望んでいますが、多くのことを試した後、JS実装は私にとってより確実に機能するように見えました。 特にこの方法
三輪健二2017

2
うまくいきませんでした:-| 代わりに、stackoverflow.com / a / 23902068/661414を使用しました。
ロイキップ2018

28
JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("javascript:window.scrollBy(250,350)");

これを試してみてください。


1
ありがとう。Seleniumの自動スクロールが原因で、クリックする必要のある要素を別の要素が覆い隠す場合に、この方法を使用する必要がありました。任意の量をスクロールして、要素を隠さずにビューポートに表示することができました。
Daniel Richnak 2012

これはFIrefox、Chrome、IEでのみ機能し、この方法はサポートされてい
ません

これがjs.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);、IEとFirefox、およびjs.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);Chromeで使用する理由です。シンプル。
IamBatman 2017年

((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");これはChromeで機能しました。そして、実際に私のために働いた唯一の解決策。最初のコメンターと同じ状況で、クリックする必要のある要素を覆い隠してしまう固定要素が下部にありました。
シルバー


15

Selenium Webdriverを使用してFirefoxウィンドウをスクロールする場合、JavaコードでJavaScriptを使用する方法の1つです。下に(Webページの下部に)スクロールするJavaScriptコードは次のとおりです。

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0, Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight));");

10

任意の要素をターゲットにしてキー送信する(または上/左/右)にも機能するようです。これはちょっとしたハックですが、スクロールの問題を解決するためにJavaScriptを使用するという考えにはあまり興味がありません。

例えば:

WebElement.sendKeys(Keys.DOWN);

これはjsを使用するのと同じくらいハックであり、本当に最も簡単なことです。これは主にIEの問題で、クリックすると要素がスクロールして表示されますが、完全には表示されません。解決策は、適切なtry / catch / loopシナリオで実行された場合、{PGUP}を使用するのと同じくらいエレガントです。
jibbs

あなたは私の日を救った!ありがとう
イェスコR.

私の場合、ページダウンはうまくいったものでした。これは素晴らしいハックです(すべてのjsハックに対して)。
akostadinov

@DevDaveに感謝!C#で同等:var elem = driver.FindElement(By.Id("element_id")); elem.SendKeys(Keys.PageDown);
ワト

9
webElement = driver.findElement(By.xpath("bla-bla-bla"));
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", webElement);

その他の例については、こちらをご覧ください。すべてロシア語ですが、Javaコードは異文化です:)


このソリューションに-1がある理由を理解できますか?
josephnvu 2015

Firefoxでのみ機能するためです。他のブラウザはこのメソッドをサポートしていません。
ウェインアレン

上記のドキュメントをロシア語から翻訳する必要がある場合は、喜んでお手伝いします。
monkrus

8

Seleniumでは、JavaScriptエグゼキューターの助けを借りて、要素までスクロールするか、ページをスクロールする必要があります。

je.executeScript("arguments[0].scrollIntoView(true);", element);

上記のステートメントで elementは、スクロールする必要がある正確な要素です。上記のコードを試したところ、うまくいきました。

これに関する完全な投稿とビデオがあります:

http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver/


@Mukesh otwani上記のコードは下にスクロールしますが、定義されているピクセルを使用せずにabtが上にスクロールする方法です。
カーン

6

このコードスニペットを使用してスクロールできます。

C#

var element = Driver.FindElement(By.Id("element-id"));
Actions actions = new Actions(Driver);
actions.MoveToElement(element).Perform();

そこにあります


6

これは私のために働きました:

IWebElement element = driver.FindElements(getApplicationObject(currentObjectName, currentObjectType, currentObjectUniqueId))[0];
 ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element);

5

Selenium 2は要素までスクロールしてからクリックしようとします。これは、Selenium 2が表示されていると見なさない限り、要素と相互作用しないためです。

要素へのスクロールは暗黙的に行われるため、アイテムを見つけて操作するだけです。


19
これは質問に対する答えですか?
reinierpost 2012

57
私にとってそのように機能していないようです。表示されていない要素に対して「要素がクリックできません」というエラーが表示される
DevDave

5
@DevDave同じ問題がありますが、私の場合、セレンは要素に対してクリックアクションを実行せず、例外はありません。以前は問題がなく、何が原因なのかわかりません。
Zeinab Abbasimazar 2013年

5
暗黙的なスクロールはブラウザによって異なります。ページの途中にあるポップアップメニューの要素のテストがあります。Ruby gem selenium_webdriver 2.43を使用すると、chromium-browser 37(およびInternet Explorer)がメニュー項目を実際にスクロールして表示し、クリックします。しかし、Firefox 32はまったくスクロールしていないように見え、「要素は現在表示されていないため、操作できない可能性があります」というエラーで失敗します。
スキーヤーページ2014

9
この答えは間違っています。Selenium 2.0の仕様によるWebElement.click()と、要素をクリックして表示する必要があります。あなたに代わってスクロールしません。
ギリ

5

ドライバを使用して、pagedownまたはキーのようなキーを送信しdownarrow、要素を表示します。私はそれが単純すぎる解決策であり、すべての場合に適用できるとは限らないことを知っています。


1
これはナンセンスです。大きなページに数十ページを送信しなければならない場合があります。それは遅く、信頼できません。
Elmue

2
はい。同意する。しかし、私は「すべての場合に該当するわけではない」と言いました
ガネーシュS

element表示可能なページで既知のものを見つけて、PageDownを送信するのがelement.SendKeys(Keys.PageDown);うまくいきました。
Gokul 2017年

ページをスクロールしないようにAltキーを使用し、try / except(Python)句を使用して、一部の要素にキーを送信するときに発生する可能性のあるエラーを処理することをお勧めします。
Alex K.

4

私の経験では、ページに複数のスクロール可能なセクションがある場合、Selenium Webdriverはクリック時に要素に自動スクロールしません(これは非常に一般的です)。

私はRubyを使用していますが、AUTの場合、次のようにクリックメソッドにモンキーパッチを適用する必要がありました。

class Element

      #
      # Alias the original click method to use later on
      #
      alias_method :base_click, :click

      # Override the base click method to scroll into view if the element is not visible
      # and then retry click
      #
      def click
        begin
          base_click
        rescue Selenium::WebDriver::Error::ElementNotVisibleError
          location_once_scrolled_into_view
          base_click
        end
      end

「location_once_scrolled_into_view」メソッドは、WebElementクラスの既存のメソッドです。

Rubyを使用していない可能性がありますが、いくつかのアイデアが得られるはずです。


上で宣言したので、の代わりmodule Capybara :: module Nodeに呼び出す必要がnative.location_once_scrolled_into_viewありましたlocation_once_scrolled_into_view。私も救いました::Selenium::WebDriver::Error::UnknownError。これは、Firefox 44.0.2で頻繁に得られるものです。しかし、私はこの解決策は十分に柔軟ではなく、最終的<Element>.native.location_once_scrolled_into_viewには受け入れテスト自体に電話をかけ、その後すぐpage.execute_script('window.scrollByPages(-1)')に必要なところに行きます。
Al Chou、

WatirはElement#scroll_into_viewSeleniumに委任するメソッドを持っていlocation_once_scrolled_into_viewます。しかし、どちらもSeleniumのデフォルトの動作と何も変わらないので、オーバーフロー要素は、クリックしようとするものを妨害する可能性があります。
akostadinov

3

要素をスクロールして表示するRubyスクリプトは次のとおりです。

$driver.execute_script("arguments[0].scrollIntoView(true);", element)
sleep(3)
element.click

2

Seleniumでのスクロールの問題に直面することもありました。そこで、javaScriptExecuterを使用してこれを実現しました。

下にスクロールする場合:

WebDriver driver = new ChromeDriver();
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollBy(0, 250)", "");

または、

js.executeScript("scroll(0, 250);");

上にスクロールするには:

js.executeScript("window.scrollBy(0,-250)", "");

または、

js.executeScript("scroll(0, -250);");

2

他の答えがあまりにもハッキリだと思うなら、これもハックですが、JavaScriptインジェクションは含まれていません。

ボタンが画面から外れると、ボタンが壊れてスクロールするので、再試行してください...¯\ _(ツ)_ /¯

try
{
    element.Click();
}
catch {
    element.Click();
}

2

これはJavaScriptで繰り返されるソリューションですが、要素を待機する要素が追加されています。

それ以外の場合ElementNotVisibleExceptionは、要素で何らかのアクションが実行されている場合に表示されることがあります。

this.executeJavaScriptFunction("arguments[0].scrollIntoView(true);", elementToBeViewable);
WebDriverWait wait = new WebDriverWait(getDriver(), 5);
wait.until(ExpectedConditions.visibilityOf(elementToBeViewable));

?? <-どういう意味ですか?
チェ

1

この方法で要素をスクロールしてクリックしました:

List<WebElement> image = state.getDriver().findElements(By.xpath("//*[contains(@src,'image/plus_btn.jpg')]"));

for (WebElement clickimg : image)
{
  ((JavascriptExecutor) state.getDriver()).executeScript("arguments[0].scrollIntoView(false);", clickimg);
  clickimg.click();
}

私の場合、scrollIntoView(false)機能しましたが機能scrollIntoView(true)しませんでした。どちらでも機能しますが、シナリオによって異なります。
rsenna

私の場合は反対です-真の作品は、偽は失敗しますが、クリックが行く限り。それはfalseの場合は正しくスクロールし、私が好むものですが、何らかの理由でSeleniumはクリックしても表示されません。真のスクロールを使用すると、すべてが高すぎますが、少なくとも機能します。
Bill Hileman 2017年

ユーザーのsendkeysは可能な限りクリックではなく入力する-ブラウザーが100%ズームでない場合の問題を回避します。
Zunair

1
def scrollToElement(element: WebElement) = {
  val location = element.getLocation
  driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});")
}

1

JavaScriptを使用して、ページのスクロールWeb要素とWebページ-Selenium WebDriverにアクセスすることをお勧めします。

public static void main(String[] args) throws Exception {

    // TODO Auto-generated method stub
    FirefoxDriver ff = new FirefoxDriver();
    ff.get("http://toolsqa.com");
    Thread.sleep(5000);
    ff.executeScript("document.getElementById('text-8').scrollIntoView(true);");
}

@AbhishekBedi Chromeでもサポートされていることを覚えています。あなたが直面したかもしれない特定の問題?
virusrocks

1

スクロールのほとんどの状況で、このコードは機能します。

WebElement element = driver.findElement(By.xpath("xpath_Of_Element"));                 
js.executeScript("arguments[0].click();",element);

1

JAVA

x y位置を利用して要素までスクロールしJavascriptExecutor、これを引数として使用してください:"window.scrollBy(x, y)"

インポート後:

import org.openqa.selenium.WebElement;
import org.openqa.selenium.JavascriptExecutor;

まずx y、要素の場所を取得する必要があります。

//initialize element
WebElement element = driver.findElement(By.id("..."));

//get position
int x = element.getLocation().getX();
int y = element.getLocation().getY();

//scroll to x y 
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(" +x +", " +y +")");

1

質問がまだ関連しているかどうかはわかりませんが、https: //developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewからscrollIntoViewのドキュメントを参照した後

最も簡単な解決策は

executor.executeScript("arguments[0].scrollIntoView({block: \"center\",inline: \"center\",behavior: \"smooth\"});",element);

これにより、要素がページの中央にスクロールします。


0

Seleniumのデフォルトの動作では、要素がビューポートの上部にほとんど見えないようにスクロールします。また、すべてのブラウザがまったく同じ動作をするわけではありません。これは非常に不満です。私が行っているように、ブラウザーテストのビデオを記録する場合は、要素をスクロールして表示し、垂直方向の中央に配置する必要があります。ます。

これがJavaの私の解決策です:

public List<String> getBoundedRectangleOfElement(WebElement we)
{
    JavascriptExecutor je = (JavascriptExecutor) driver;
    List<String> bounds = (ArrayList<String>) je.executeScript(
            "var rect = arguments[0].getBoundingClientRect();" +
                    "return [ '' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height) ]", we);
    System.out.println("top: " + bounds.get(1));
    return bounds;
}

そして、スクロールするには、次のように呼び出します。

public void scrollToElementAndCenterVertically(WebElement we)
{
    List<String> bounds = getBoundedRectangleOfElement(we);
    Long totalInnerPageHeight = getViewPortHeight(driver);
    JavascriptExecutor je = (JavascriptExecutor) driver;
    je.executeScript("window.scrollTo(0, " + (Integer.parseInt(bounds.get(1)) - (totalInnerPageHeight/2)) + ");");
    je.executeScript("arguments[0].style.outline = \"thick solid #0000FF\";", we);
}

getViewPortHeight関数がありません...ターゲット要素の高さを想定している
Shubham Jain

0

PHP webDriver for Seleniumでこれを行う方法を次に示します。Seleniumスタンドアロンサーバー2.39.0 + https://github.com/Element-34/php-webdriver + Firefox 25.0で動作します

$element=$session->welement("xpath", "//input[@value='my val']");
$element->click();
$element=$session->welement("xpath", "//input[@value='ma val2']");
$element->location_in_view(); // < -- this is the candy
$element->click();

注:私はElement34 PHP-webdriverのカスタマイズバージョンを使用しています。ただし、コアに変更はありません。「element」の代わりに「welement」を使用します。しかし、それは問題の事件に影響を与えません。ドライバーの作成者は、「ほとんどすべてのAPI呼び出しが、WebDriverプロトコル自体で定義されているものを直接変換できるようにする」と述べています。したがって、他のプログラミング言語で問題はないはずです。

クリックするだけでは私の設定では機能しません。クリックの代わりにスクロールするので、「location_in_view()」を呼び出さずに2回クリックする必要がありました。

注:このメソッドは、タイプボタンの入力など、表示可能な要素に対して機能します。

見てくださいhttp : //code.google.com/p/selenium/wiki/JsonWireProtocol#/session/ : sessionId / element /: id / location

JsonWireProtocol#の説明では、location _in_viewは内部メソッドであるため、location + movetoの使用を提案しています。


0

私にとってうまくいったことの1つは、ブラウザーウィンドウの下部にある要素でBrowser.MoveMouseToElementメソッドを使用することでした。奇跡的に、それはInternet Explorer、Firefox、およびChromeで機能しました。

ハックが少ないと感じたからといって、JavaScriptインジェクション手法ではなくこれを選択しました。


これはどのプログラミング言語ですか?
akostadinov

0

私はADFコンポーネントを使用してテストを行っており、遅延読み込みを使用する場合は、スクロールのための個別のコマンドが必要です。オブジェクトがロードされておらず、Seleniumを使用してオブジェクトを検索しようとすると、Seleniumはelement-not-found例外をスローします。


0

何も機能しない場合は、クリックする前にこれを試してください。

public void mouseHoverJScript(WebElement HoverElement) {

    String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
    ((JavascriptExecutor) driver).executeScript(mouseOverScript, HoverElement);
}

0

Javaでは、次のコードのように、JavaScriptを使用してスクロールできます。

driver.getEval("var elm = window.document.getElementById('scrollDiv'); if (elm.scrollHeight > elm.clientHeight){elm.scrollTop = elm.scrollHeight;}");

「elm.scrollTop」変数に必要な値を割り当てることができます。


0

解決策は次のとおりです。

public void javascriptclick(String element)
{
    WebElement webElement = driver.findElement(By.xpath(element));
    JavascriptExecutor js = (JavascriptExecutor) driver;

    js.executeScript("arguments[0].click();", webElement);
    System.out.println("javascriptclick" + " " + element);
}

0

このコードは私のために働いています:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250, 350)");

私のために働く。Dart WebDriverの実装にはまだアクションがありません。
ギュンターZöchbauer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.