Scorri l'elemento in Visualizza con selenio


208

Esiste un modo in Selenium 1.xo 2.x per scorrere la finestra del browser in modo che un particolare elemento identificato da un XPath sia in vista del browser? Esiste un metodo di messa a fuoco in Selenio, ma non sembra scorrere fisicamente la vista in FireFox. Qualcuno ha qualche suggerimento su come farlo?

Il motivo per cui ho bisogno di questo è che sto testando il clic di un elemento sulla pagina. Sfortunatamente l'evento non sembra funzionare a meno che l'elemento non sia visibile. Non ho il controllo del codice che viene generato quando si fa clic sull'elemento, quindi non posso eseguire il debug o modificarlo, quindi la soluzione più semplice è quella di scorrere l'elemento in vista.


Puoi provare questo hacky se nient'altro funziona per te : stackoverflow.com/a/53771434/7093031
YB Causa

Risposte:


215

Ho provato molte cose rispetto allo scorrimento, ma il codice seguente ha fornito risultati migliori.

Questo scorrerà fino a visualizzare l'elemento:

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
Questa è una soluzione accurata per quando potresti avere un elemento con position: fixedsulla tua pagina e sta oscurando l'elemento che Selenium vuole fare clic. Abbastanza spesso questi elementi fissi vanno nella parte inferiore, quindi l'impostazione si scrollIntoView(true)sposta piacevolmente nella parte superiore della finestra.
Mandible79,

3
Basato sull'ultima versione del selenio (2.53), questa è ora un'ottima soluzione di supporto. Il selenio non fa sempre scorrere l'elemento in vista, quindi questo è sicuramente utile.
Zoidberg,

20
Passa truea scrollIntoViewse l'oggetto a cui stai scorrendo si trova sotto la tua posizione attuale, falsese l'oggetto a cui stai scorrendo si trova sopra la tua posizione attuale. Ho avuto difficoltà a capirlo.
Big Money,

2
Perché hai bisogno di sleep thread? executeScript dovrebbe essere sincrono
riccardo.tasso

1
@ riccardo.tasso un sonno potrebbe essere stato implementato per gestire l'ignoto dell'app di destinazione. Se ha lo scorrimento dinamico o un'app a pagina singola che carica il bit successivo della pagina dopo lo scorrimento, tra le altre possibilità. Parlando per esperienza, Selenium ha spesso rotto il sito della mia azienda perché l'azione automatizzata si è verificata più velocemente di quanto Javascript potesse completare, e quindi ha superato un modello di dati incompleto. Alcuni posti potrebbero considerarlo un bug, ma mi è stato detto "Nessun essere umano potrebbe mai invocare uno scenario del genere, quindi non è un vero bug". È la vita.
Solonotix,

157

Puoi usare la org.openqa.selenium.interactions.Actionsclasse per spostarti su un elemento.

Giava:

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

Pitone:

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

7
Funzionerà se WebElement non si trova nella porta di visualizzazione?
virusrocks

9
@Dominik: In che modo Selenium sposta il mouse su un elemento esterno allo schermo? OBVIOUSLY deve prima scorrere l'elemento in vista e quindi spostare il mouse su di esso. L'ho provato. Questo codice funziona su Firefox Webdriver 2.48 ma è presente un bug: quando si dispone di un iframe in una pagina, lo scorrimento non funziona correttamente nell'iframe mentre element.LocationOnScreenOnceScrolledIntoView scorre correttamente. (Anche se la documentazione dice che questo comando restituisce solo una posizione, scorre anche!)
Elmue,

8
I documenti su seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/… ora indicano chiaramente "Sposta il mouse al centro dell'elemento. L'elemento viene fatto scorrere in vista e la sua posizione viene calcolata usando getBoundingClientRect."
George Pantazes,

5
Il codice sopra è "il modo ufficiale" Java Selenium vuole che tu faccia scorrere un elemento nel viewport, tuttavia dopo aver provato molte cose l'implementazione di JS sembrava funzionare in modo più affidabile per me. Questo metodo in particolare.
Kenji Miwa,

2
Non ha funzionato per me: - | Utilizzato invece stackoverflow.com/a/23902068/661414 .
Leukipp,

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

Potresti provare questo.


1
Grazie. Avevo bisogno di usare questo metodo nel caso in cui lo scorrimento automatico di un selenio causasse un altro elemento per oscurare l'elemento su cui dovevo fare clic. Sono stato in grado di scorrere una quantità arbitraria per rendere visibile l'elemento nella finestra, senza essere oscurato.
Daniel Richnak,

Funzionerà solo su FIrefox, Chrome e IE non supporta questo metodo
virusrocks

Questo è il motivo per cui usi js.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);per IE e Firefox e js.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);per Chrome. Semplice.
IamBatman,

((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");Questo ha funzionato in Chrome. E l'unica soluzione che ha funzionato davvero per me. Stessa situazione del primo commentatore, avevo un elemento fisso in fondo che continuava a oscurare l'elemento su cui avevo bisogno di fare clic.
argento


15

Se vuoi scorrere la finestra di Firefox usando il webdriver Selenium, uno dei modi è usare JavaScript nel codice Java. Il codice JavaScript per scorrere verso il basso (fino alla fine della pagina Web) è il seguente:

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

10

Anche il targeting di qualsiasi elemento e l' invio di tasti giù (o su / sinistra / destra) sembrano funzionare. So che questo è un po 'un trucco, ma non mi piace l'idea di utilizzare JavaScript per risolvere il problema di scorrimento.

Per esempio:

WebElement.sendKeys(Keys.DOWN);

Questo non è meno di un hack che usare js ed è davvero la cosa più semplice. Ho trovato questo principalmente un problema con IE in cui un clic tenta di far scorrere l'elemento in vista ma non lo rende del tutto. La soluzione è altrettanto elegante usando {PGUP} se fatto con lo scenario try / catch / loop corretto.
jibbs

Mi hai salvato la giornata! Grazie
Jesko R.

Nel mio caso la pagina giù era la cosa che funzionava. Questo è un bel trucco (contro tutti i js hack).
Akostadinov

Grazie @DevDave! Equivalente in C #:var elem = driver.FindElement(By.Id("element_id")); elem.SendKeys(Keys.PageDown);
Watth

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

Per altri esempi, vai qui . Tutto in russo, ma il codice Java è interculturale :)


Posso capire perché esiste un -1 per questa soluzione?
josephnvu,

Perché funziona solo con Firefox. Nessun altro browser supporta questo metodo.
Wayne Allen,

Se qualcuno ha bisogno di una traduzione dal russo per il documento di cui sopra, sarà felice di aiutarti.
monkrus

8

In Selenium dobbiamo prendere l'aiuto di un esecutore JavaScript per scorrere fino a un elemento o scorrere la pagina:

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

Nell'affermazione sopra elementè l'elemento esatto in cui dobbiamo scorrere. Ho provato il codice sopra e ha funzionato per me.

Ho un post completo e un video su questo:

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


@Mukesh otwani il codice sopra scorrerà verso il basso, ma come scorrere verso l'alto senza usare i pixel definiti in esso.
Khan,

6

Puoi utilizzare questo frammento di codice per scorrere:

C #

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

Ecco qua


6

Questo ha funzionato per me:

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

5

Il selenio 2 tenta di scorrere fino all'elemento e quindi fare clic su di esso. Questo perché il selenio 2 non interagirà con un elemento se non pensa che sia visibile.

Lo scorrimento dell'elemento avviene in modo implicito, quindi devi solo trovare l'elemento e quindi lavorare con esso.


19
In che modo questa è una risposta alla domanda?
reinierpost,

57
non sembra funzionare in quel modo per me.
Ricevo

5
@DevDave Ho lo stesso problema, tranne nel mio caso, il selenio non esegue l'azione di clic sull'elemento e non ci sono eccezioni. Non ho avuto il problema prima e non so cosa l'abbia causato.
Zeinab Abbasimazar,

5
Lo scorrimento implicito varia tra i browser. Ho un test di un elemento in un menu a comparsa a metà pagina. Con la gemma di Ruby selenium_webdriver 2.43 trovo chromium-browser 37 (e credo che Internet Explorer) faccia scorrere la voce del menu in vista e la faccia clic. Ma Firefox 32 non sembra scorrere affatto, quindi non riesce con "L'elemento non è attualmente visibile e quindi potrebbe non essere interagito con".
skierpage

9
Questa risposta è sbagliata Secondo le specifiche per Selenium 2.0, WebElement.click()l'elemento deve essere visibile per poter fare clic su di esso. Non scorrerà per tuo conto.
Gili,

5

Utilizzare il driver per inviare chiavi come la chiave pagedowno downarrowper visualizzare l'elemento. So che è una soluzione troppo semplice e potrebbe non essere applicabile in tutti i casi.


1
Questo non ha senso. Potrebbe essere necessario inviare una dozzina di pagine su una pagina di grandi dimensioni. È lento e non affidabile.
Elmue,

2
Sì. Sono d'accordo. Ma ho detto "non applicabile in tutti i casi"
Ganesh S,

Trovare alcuni noti elementnella pagina visualizzabile e inviare PageDown ha element.SendKeys(Keys.PageDown);funzionato per me.
Gokul,

Consiglio di usare il tasto Alt in modo da non scorrere la pagina e usare la clausola try / tranne (Python) per gestire gli errori che possono verificarsi durante il tentativo di inviare le chiavi ad alcuni elementi.
Alex K.

4

Dalla mia esperienza, Selenium Webdriver non scorre automaticamente fino a un elemento su clic quando ci sono più di una sezione scorrevole sulla pagina (che è abbastanza comune).

Sto usando Ruby, e per il mio AUT ho dovuto scimmiottare il metodo click come segue;

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

Il metodo 'location_once_scrolled_into_view' è un metodo esistente sulla classe WebElement.

Mi rendo conto che potresti non usare Ruby, ma dovrebbe darti alcune idee.


Ho dichiarato quanto sopra in module Capybara :: module Nodee ho dovuto chiamare native.location_once_scrolled_into_viewinvece di solo location_once_scrolled_into_view. Ho anche salvato ::Selenium::WebDriver::Error::UnknownError, che è quello che ottengo spesso in Firefox 44.0.2. Ma trovo che questa soluzione non sia abbastanza flessibile e alla fine inserisco le <Element>.native.location_once_scrolled_into_viewchiamate nel test di accettazione stesso, seguito immediatamente da page.execute_script('window.scrollByPages(-1)')dove necessario.
Al Chou,

Watir ha il metodo Element#scroll_into_viewche delega a Selenium location_once_scrolled_into_view. Ma entrambi non fanno nulla di diverso dal comportamento predefinito di Seleniums, quindi gli elementi di overflow possono comunque ostacolare qualsiasi cosa proviamo a fare clic.
Akostadinov

3

Lo script Ruby per lo scorrimento di un elemento in vista è il seguente.

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

2

A volte ho anche affrontato il problema dello scorrimento con selenio. Per questo ho usato javaScriptExecuter.

Per scorrere verso il basso:

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

O anche

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

Per scorrere verso l'alto:

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

O,

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

2

Se ritieni che le altre risposte siano troppo confuse, anche questa è risposta, ma non è prevista alcuna iniezione JavaScript.

Quando il pulsante è fuori dallo schermo, si interrompe e scorre fino a esso, quindi riprovare ... ¯ \ _ (ツ) _ / ¯

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

2

Questa è una soluzione ripetuta con JavaScript, ma con un elemento in attesa aggiunto.

Altrimenti ElementNotVisibleExceptionpotrebbe apparire se si sta eseguendo un'azione sull'elemento.

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

?? <- cosa significa?
Choi,

1

Ho usato questo modo per scorrere l'elemento e fare clic:

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();
}

Nel mio caso, ha scrollIntoView(false)funzionato, ma scrollIntoView(true)non l'ha fatto. Entrambi possono funzionare , dipende dal tuo scenario.
rsenna,

Il mio caso è l'opposto: il vero funziona, il falso fallisce, ma solo per quanto riguarda il clic. Scorre correttamente per falso, ed è quello che preferisco, ma per qualsiasi motivo Selenium non può ancora vederlo per un clic. Utilizzando true scorre tutto troppo in alto, ma almeno funziona.
Bill Hileman,

Le sendkeys dell'utente entrano invece del clic quando possibile - evita problemi se il browser non ha lo zoom al 100%.
Zunair,

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

1

Potresti voler visitare la pagina Scorri gli elementi Web e la pagina Web - Selenium WebDriver usando Javascript :

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 Ricordo che è supportato anche in Chrome. Qualche problema specifico che potresti avere affrontato?
virusrocks

1

Nella maggior parte delle situazioni di scorrimento questo codice funzionerà.

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

1

GIAVA

Prova di scorrimento per elemento utilizzare x yla posizione, e l'uso JavascriptExecutordi questo è argomento: "window.scrollBy(x, y)".

Seguente importazione:

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

Per prima cosa devi ottenere la x yposizione dell'elemento.

//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 +")");


0

Il comportamento predefinito di Selenium ci consente di scorrere in modo che l'elemento sia appena visibile nella parte superiore della finestra. Inoltre, non tutti i browser hanno lo stesso identico comportamento. Questo è molto spiacevole. Se registri video dei test del browser, come faccio io, quello che vuoi è che l'elemento scorra in vista e sia centrato verticalmente .

Ecco la mia soluzione per 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;
}

E poi, per scorrere, lo chiami così:

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);
}

La funzione getViewPortHeight non è presente ... Supponendo che stai prendendo l'altezza dell'elemento target
Shubham Jain,

0

Ecco come lo faccio con PHP webDriver per Selenium. Funziona con il server autonomo 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();

Nota: utilizzo una versione personalizzata di Element34 PHP-webdriver. Ma non c'è alcun cambiamento nel nucleo. Uso solo il mio "welement" invece di "element". Ma non ha alcuna influenza sul caso in questione. L'autore del driver afferma che "consentire a quasi tutte le chiamate API di essere una trasformazione diretta di ciò che è definito nel protocollo WebDriver stesso". Quindi non dovresti avere problemi con altri linguaggi di programmazione.

Il semplice clic non funzionerà nella mia configurazione. Farà scorrere invece di fare clic, quindi ho dovuto fare due volte clic senza chiamare "location_in_view ()".

Nota: questo metodo funziona per gli elementi che possono essere visualizzati, come un input di tipo pulsante.

Dai un'occhiata a: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location

La descrizione per JsonWireProtocol # suggerisce l'utilizzo di location + moveto, poiché location _in_view è un metodo interno.


0

Qualcosa che ha funzionato per me era usare il metodo Browser.MoveMouseToElement su un elemento nella parte inferiore della finestra del browser. Miracolosamente ha funzionato in Internet Explorer, Firefox e Chrome.

Ho scelto questo sulla tecnica di iniezione JavaScript solo perché mi sembrava meno confuso.


Quale linguaggio di programmazione è questo?
Akostadinov

0

Ho effettuato dei test con i componenti ADF e devi utilizzare un comando separato per lo scorrimento se viene utilizzato il caricamento lento. Se l'oggetto non viene caricato e si tenta di trovarlo utilizzando il selenio, il selenio genererà un'eccezione non trovata nell'elemento.


0

Se non funziona nulla, prova questo prima di fare clic su:

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

In Java possiamo scorrere usando JavaScript, come nel seguente codice:

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

È possibile assegnare un valore desiderato alla variabile "elm.scrollTop".


0

Una soluzione è:

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

Questo codice funziona per me:

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

Per me va bene. L'implementazione di Dart WebDriver non ha ancora azioni.
Günter Zöchbauer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.