Elemento de Rolagem na Visualização com Selênio

Existe alguma maneira no Selenium 1.x ou 2.x para rolar a janela do navegador para que um determinado elemento identificado por um XPath esteja à vista do navegador? Há um método de foco no Selenium, mas não parece rolar fisicamente a exibição no FireFox. Alguém tem alguma sugestão sobre como fazer isso?

A razão pela qual eu preciso disso é que estou testando o clique de um elemento na página. Infelizmente, o evento parece não funcionar, a menos que o elemento esteja visível. Eu não tenho controle do código que é acionado quando o elemento é clicado, por isso não posso depurar ou fazer modificações nele, portanto, a solução mais fácil é rolar o item para a visualização.

   

Já tentei muitas coisas com relação a rolagem, mas o código abaixo forneceu melhores resultados.

Isso rolará até que o elemento esteja visível:

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 

Você pode usar a class org.openqa.selenium.interactions.Actions para mover para um elemento:

 WebElement element = driver.findElement(By.id("my-id")); Actions actions = new Actions(driver); actions.moveToElement(element); actions.perform(); 
 JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("javascript:window.scrollBy(250,350)"); 

Você pode querer tentar isso.

Se você quiser rolar na janela do Firefox usando o selenium webdriver, uma das maneiras é usar JavaScript no código Java. O código JavaScript para rolar para baixo (para a parte inferior da página da web) é o seguinte:

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

Selênio 2 tenta rolar para o elemento e depois clicar nele. Isso ocorre porque o Selenium 2 não irá interagir com um elemento, a menos que ache que é visível.

Rolando para o elemento acontece implicitamente, então você só precisa encontrar o item e depois trabalhar com ele.

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

Para mais exemplos, clique aqui . Tudo em russo, mas o código Java é cross-cultural 🙂

Segmentar qualquer elemento e enviar chaves para baixo (ou para cima / esquerda / direita) parece funcionar também. Eu sei que isso é um pouco complicado, mas também não entendo a idéia de usar JavaScript para resolver o problema de rolagem.

Pela minha experiência, o Selenium Webdriver não rola automaticamente para um elemento ao clicar quando há mais de uma seção rolável na página (o que é bastante comum).

Eu estou usando Ruby, e para o meu AUT, eu tive que corrigir o método click como 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 

O método ‘location_once_scrolled_into_view’ é um método existente na class WebElement.

Eu aprecio você não pode estar usando Ruby, mas deve dar-lhe algumas ideias.

Você pode usar este snippet de código para rolar:

C #

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

Você tem isso

Use o driver para enviar chaves como a chave pagedown ou downarrow para exibir o elemento. Eu sei que é uma solução muito simples e pode não ser aplicável em todos os casos.

Em Selenium, precisamos da ajuda de um executor JavaScript para rolar para um elemento ou rolar a página:

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

No element instrução acima, é o elemento exato em que precisamos rolar.

Eu tentei o código acima, e funcionou para mim.

Eu tenho um post completo e um vídeo sobre isso:

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

Às vezes, também enfrentei o problema de rolar com o Selenium. Então eu usei javaScriptExecuter para conseguir isso.

Para rolar para baixo:

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

Ou também

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

Para rolar para cima:

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

Ou,

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

Isso funcionou para mim:

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

Se você acha que outras respostas eram muito hacky, esta também é, mas não há injeção de JavaScript envolvida.

Quando o botão está fora da canvas, ele quebra e rola para ele, então tente novamente … ¯ \ _ (ツ) _ / ¯

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

Eu usei este caminho para rolar o elemento e clique em:

 List 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(); } 
 def scrollToElement(element: WebElement) = { val location = element.getLocation driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});") } 

O script Ruby para a rolagem de um elemento é mostrado abaixo.

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

Convém visitar os elementos da Web de rolagem da página e a página da 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);"); } 

O selenium pode rolar para algum elemento na barra de rolagem automaticamente para uma interface simples, mas para a interface de carregamento lento, scrollToElement ainda é necessário.

Esta é minha implementação em Java com JavascriptExecutor. Você pode encontrar mais detalhes no código-fonte do Satix: http://www.binpress.com/app/satix-seleniumbased-automation-testing-in-xml/1958

 public static void perform(WebDriver driver, String Element, String ElementBy, By by) throws Exception { try{ //long start_time = System.currentTimeMillis(); StringBuilder js = new StringBuilder(); String browser = "firefox"; if (ElementBy.equals("id")) { js.append("var b = document.getElementById(\"" + Element + "\");"); } else if (ElementBy.equals("xpath")) { if (!"IE".equals(browser)) { js.append("var b = document.evaluate(\"" + Element + "\", document, null, XPathResult.ANY_TYPE, null).iterateNext();"); } else { throw new Exception("Action error: xpath is not supported in scrollToElement Action in IE"); } } else if (ElementBy.equals("cssSelector")) { js.append("var b = document.querySelector(\"" + Element + "\");"); } else { throw new Exception("Scroll Action error"); } String getScrollHeightScript = js.toString()+ "var o = new Array(); o.push(b.scrollHeight); return o;"; js.append("b.scrollTop = b.scrollTop + b.clientHeight;"); js.append("var tmp = b.scrollTop + b.clientHeight;"); js.append("var o = new Array(); o.push(tmp); return o;"); int tries = 1; String scrollTop = "0"; while (tries > 0){ try{ String scrollHeight = ((JavascriptExecutor)driver).executeScript(getScrollHeightScript).toString(); if (scrollTop.equals(scrollHeight)) { break; } else if (driver.findElement(by).isDisplayed()) { break; } Object o = ((JavascriptExecutor)driver).executeScript(js.toString()); scrollTop = o.toString(); Thread.sleep(interval); tries ++; }catch(Exception e){ throw new Exception("Action error:" + " javascript execute error : " + e.getMessage() + ", javascript : " + js.toString()); } } }catch (Exception e) { try { ScreenshotCapturerUtil.saveScreenShot(driver, CLASSNAME); } catch (IOException e1) { throw new Exception("Save screenshot error!", e1); } throw e; } } 

O comportamento padrão do Selenium é rolar para que o elemento mal esteja visível no topo da viewport. Além disso, nem todos os navegadores têm exatamente o mesmo comportamento. Isso é muito insatisfatório. Se você gravar vídeos dos testes do seu navegador, como eu faço, o que você quer é que o elemento seja exibido na canvas e seja centralizado verticalmente .

Aqui está a minha solução para Java:

 public List getBoundedRectangleOfElement(WebElement we) { JavascriptExecutor je = (JavascriptExecutor) driver; List bounds = (ArrayList) 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 então, para rolar, você chama assim:

 public void scrollToElementAndCenterVertically(WebElement we) { List 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); } 

Aqui está como eu faço isso com o PHP webDriver for Selenium. Funciona para o servidor independente 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: Eu uso uma versão personalizada do Element34 PHP-webdriver. Mas não há nenhuma mudança no núcleo. Eu apenas uso o meu “welement” em vez de “element”. Mas isso não influencia o caso em questão. O autor do driver diz “permitir que quase todas as chamadas de API sejam uma transformação direta do que é definido no próprio protocolo WebDriver”. Então você não deve ter problemas com outras linguagens de programação.

Basta clicar em não funcionará na minha configuração. Ele fará uma rolagem em vez de clicar, então eu tive que clicar duas vezes sem chamar “location_in_view ()”.

Nota: Este método funciona para elementos que podem ser visualizados, como uma input do tipo botão.

Dê uma olhada em: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location

A descrição para JsonWireProtocol # sugere o uso de location + moveto, porque location _in_view é um método interno.

Algo que funcionou para mim foi usar o método Browser.MoveMouseToElement em um elemento na parte inferior da janela do navegador. Milagrosamente funcionou no Internet Explorer, Firefox e Chrome.

Eu escolhi isso sobre a técnica de injeção de JavaScript só porque parecia menos hacky.

Eu tenho feito testes com componentes ADF e você tem que ter um comando separado para rolar se o carregamento lento é usado. Se o object não estiver carregado e você tentar encontrá-lo usando o Selenium, o Selenium lançará uma exceção de elemento não encontrado.

Se nada funcionar, tente isso antes de clicar:

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

Em Java, podemos rolar usando JavaScript, como no código a seguir:

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

Você pode atribuir um valor desejado à variável “elm.scrollTop”.

Uma solução é:

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

Esta é uma solução repetida com JavaScript, mas com um elemento de espera adicional.

Caso contrário, ElementNotVisibleException pode aparecer se alguma ação no elemento estiver sendo feita.

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

Este código está funcionando para mim:

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

Eu concordo com todos aqui, que dizem “Selenium tem uma opção de rolagem implícita”. Além disso, se você estivesse no Selenium 1 e agora tiver feito o upgrade para o Selenium 2 e procurar os comandos da versão anterior, use o comando conhecido como:

 Seleniumbackeddriver. WebDriver driver = new FirefoxDriver(); public void setUp() throws Exception { String baseUrl = "http://www.google.co.in/"; selenium = new WebDriverBackedSelenium(driver, baseUrl); } 

Você poderia fazer uso destes e usar comandos de ambas as versões.

Faça um clique random na página:

 driver.findElement(By.id("ID of a web element present below")).click 

Em seguida, execute o que você deseja fazer.