Öğeyi Selenyum ile Görünüme Kaydırma


207

Selenium 1.x veya 2.x'te tarayıcı penceresini bir XPath tarafından tanımlanan belirli bir öğenin tarayıcıyı görebileceği şekilde kaydırmanın herhangi bir yolu var mı? Selenium'da bir odaklama yöntemi var, ancak FireFox'ta görünümü fiziksel olarak kaydırmıyor gibi görünüyor. Herkes bunun nasıl yapılacağı hakkında herhangi bir öneriniz var mı?

Buna ihtiyacımın nedeni, sayfadaki bir öğenin tıklamasını test etmem. Maalesef, öğe görünür olmadığı sürece etkinlik işe yaramıyor gibi görünüyor. Öğe tıklatıldığında tetiklenen kodun denetimine sahip değilim, bu yüzden hata ayıklama veya üzerinde değişiklik yapamıyorum, bu yüzden en kolay çözüm öğeyi görünüme kaydırmaktır.


Sizin için başka hiçbir şey işe yaramazsa bu hacky birini deneyebilirsiniz : stackoverflow.com/a/53771434/7093031
YB Nedeni

Yanıtlar:


214

Kaydırma ile ilgili birçok şeyi denedim, ancak aşağıdaki kod daha iyi sonuçlar verdi.

Bu öğe görüntülenene kadar kaydırılır:

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
Bu, position: fixedsayfanızda bir öğe olduğunda ve Selenium'un tıklamak istediği öğeyi gizlediği zamanlar için düzgün bir çözümdür . Çoğu zaman bu sabit elemanlar en alta iner, bu yüzden ayar scrollIntoView(true)onu görünümün en üstüne taşır.
Mandible79

3
Selenyumun en yeni sürümüne (2.53) dayanarak, bu şimdi büyük bir yardımcı çözümdür. Selenyum her zaman öğeyi görünüme kaydırmaz, bu yüzden bu kesinlikle işe yarar.
Zoidberg

20
Geçmek trueiçin scrollIntoViewsize Kaydırırken nesne, o anda nerede altında ise falsesize Kaydırırken nesne o anda nerede üzerindeyse. Bunu anlamakta zorlandım.
Big Money

2
Neden iplik uykusuna ihtiyacınız var? executeScript eşzamanlı olmalıdır
riccardo.tasso

1
@ riccardo.tasso hedef uygulamanın bilinmeyeniyle başa çıkmak için bir uyku uygulanmış olabilir. Dinamik kaydırma özelliği varsa veya kaydırma sonrasında sayfanın sonraki bitini yükleyen tek sayfalık bir uygulama varsa diğer olasılıkların yanı sıra. Deneyimden bahsetmişken, otomatik eylem Javascript'in tamamlayabildiğinden daha hızlı gerçekleştiği için Selenium şirketimin sitesini sık sık bozdu ve böylece eksik bir veri modeli geçti. Bazı yerler bunu bir hata olarak değerlendirebilir, ancak "Hiç kimse böyle bir senaryoyu çağıramazdı, bu yüzden gerçek bir hata değil" söylendi. En la vie.
Solonotix

157

org.openqa.selenium.interactions.ActionsBir öğeye gitmek için sınıfı kullanabilirsiniz .

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 Görünüm Bağlantı Noktasında değilse bu işe yarar mı?
virusrocks

9
@Dominik: Selenyum, fareyi ekranın dışındaki bir öğeye nasıl taşıyacak? GÖRÜNÜŞLE, önce öğeyi görünüme kaydırmalı ve ardından fareyi ona taşımalıdır. Test ettim. Bu kod Firefox Webdriver 2.48 üzerinde çalışır, ancak bir hata vardır: Bir sayfada iframe varsa, element.LocationOnScreenOnceScrolledIntoView doğru kayarken kaydırma iframe'de düzgün çalışmaz. (Belgeler bu komutun yalnızca bir konum döndürdüğünü söylemesine rağmen, aynı zamanda kayar!)
Elmue

7
En dokümanlar seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/... artık açıkça devlet "öğe görüntülendiğinde kaydırılır. Elementin ortasında fareyi hareket ettirir ve konumu kullanılarak hesaplanır getBoundingClientRect."
George Pantazes

5
Yukarıdaki kod "resmi yol" Java Selenium bir öğeyi görünüm alanına kaydırmak istiyor, ancak çok şey denedikten sonra JS uygulaması bana daha güvenilir gibi görünüyordu. Özellikle bu yöntem .
Kenji Miwa

2
Benim için çalışmadı: - | Kullanılan stackoverflow.com/a/23902068/661414 yerine.
Leukipp

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

Bunu denemek isteyebilirsiniz.


1
Teşekkürler. Bu yöntemi, bir Selenyum'un otomatik kaydırmasının başka bir öğenin tıklatmam gereken öğeyi gizlemesine neden olduğu bir durumda kullanmam gerekiyordu. Öğeyi, görünmeden, görünür olmadan görünür hale getirmek için rasgele bir miktar kaydırmayı başardım.
Daniel Richnak

Bu sadece FIrefox, Chrome ve IE'de çalışacak bu yöntemi desteklemiyor
virusrocks

Bu yüzden js.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);IE ve Firefox ve js.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);Chrome için kullanıyorsunuz. Basit.
IamBatman

((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");Bu Chrome'da çalıştı. Ve benim için gerçekten işe yarayan tek çözüm. İlk yorumcu ile aynı durum, altta tıklamak için ihtiyaç duyduğum öğeyi gizleyen sabit bir öğeye sahiptim.
gümüş


15

Selenium web sürücüsünü kullanarak Firefox penceresinde ilerlemek istiyorsanız, yollardan biri Java kodunda JavaScript kullanmaktır. Aşağı kaydırılacak JavaScript kodu (web sayfasının altına) aşağıdaki gibidir:

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

10

Herhangi bir öğeyi hedeflemek ve aşağı tuşları (veya yukarı / sol / sağ) göndermek de işe yarıyor. Bunun bir kesmek olduğunu biliyorum, ama gerçekten kaydırma problemini çözmek için JavaScript kullanma fikrinde değilim.

Örneğin:

WebElement.sendKeys(Keys.DOWN);

Bu js kullanmaktan daha az bir hack değildir ve gerçekten en basit şeydir. Ben öncelikle bir tıklama öğeyi görünüme kaydırmaya çalışır ama oldukça yapmaz IE ile ilgili bir sorun buldum. Doğru deneme / yakalama / döngü senaryosu ile yapılırsa çözüm {PGUP} kullanarak zariftir.
jibbs

Günümü kurtardın! Teşekkürler
Jesko R.

Benim durumumda aşağı çalıştı bir şey oldu. Bu güzel bir kesmek (vs tüm js kesmek).
akostadinov

Teşekkürler @DevDave! C # ile eşdeğer: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);

Daha fazla örnek için buraya gidin . Hepsi Rusça, ancak Java kodu kültürler arası :)


Bu çözüm için neden -1 olduğunu anlayabilir miyim?
josephnvu

Çünkü sadece Firefox'ta çalışıyor. Başka hiçbir tarayıcı bu yöntemi desteklemez.
Wayne Allen

Birisi yukarıda belirtilen belge için Rusçadan bir çeviriye ihtiyaç duyarsa, yardımcı olmaktan memnuniyet duyarız.
monkrus

8

Selenium'da bir öğeye gitmek veya sayfayı kaydırmak için bir JavaScript yürütücüsünün yardımını almamız gerekir:

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

Yukarıdaki ifadede element, kaydırmamız gereken kesin unsurdur. Yukarıdaki kodu denedim ve benim için çalıştı.

Bu konuda tam bir yazı ve video var:

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


@Mukesh otwani yukarıdaki kod aşağı doğru kayar, ancak abt içinde tanımlanan pikselleri kullanmadan nasıl yukarı kayar.
khan

6

Bu kod snippet'ini aşağıdakileri kaydırmak için kullanabilirsiniz:

C #

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

İşte aldın


6

Bu benim için çalıştı:

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

5

Selenyum 2 öğeye ilerlemeye ve sonra üzerine tıklamaya çalışır. Bunun nedeni, Selenyum 2'nin görünür olduğunu düşünmediği sürece bir elemanla etkileşime girmeyeceğidir.

Öğeye ilerlemek örtük olarak gerçekleşir, böylece öğeyi bulup onunla çalışmanız yeterlidir.


19
Bu sorunun cevabı nasıl?
reinierpost

57
benim için böyle çalışıyor gibi görünmüyor.
Görünmeyen

5
@DevDave Benim durumum dışında, selenyum öğe üzerinde tıklama eylemi gerçekleştirmez ve istisna yoktur aynı sorun var. Daha önce problemim yoktu ve buna neyin sebep olduğunu bilmiyorum.
Zeinab Abbasimazar

5
Örtülü kaydırma tarayıcılar arasında değişiklik gösterir. Bir sayfanın aşağısında bir açılır menüde bir öğe testi var. Ruby gem selenium_webdriver 2.43 ile krom tarayıcı 37 buluyorum (ve Internet Explorer'a inanıyorum) gerçekten menü öğesini görünüme kaydırıyor ve tıklıyor. Ancak Firefox 32 hiç kaydırma yapmıyor gibi görünüyor ve "Element şu anda görünmüyor ve bu nedenle etkileşimde bulunmayabilir" ile başarısız oluyor.
kayakçı Sayfa

9
Bu cevap yanlış. Selenium 2.0 spesifikasyonuna göre, WebElement.click()üzerine tıklamak için elemanın görünür olmasını gerektirir. Sizin adınıza kaydırılmaz.
Gili

5

Öğeyi görünüme getirmek için pagedownveya downarrowtuşu gibi anahtarlar göndermek için sürücüyü kullanın . Bunun çok basit bir çözüm olduğunu biliyorum ve her durumda geçerli olmayabilir.


1
Bu saçmalık. Büyük bir sayfaya bir düzine sayfa göndermeniz gerekebilir. Yavaş ve güvenilir değil.
Elmue

2
Evet. Katılıyorum. Ama "her durumda geçerli değil" dedim
Ganesh S

elementGörüntülenebilir sayfada bilinenler bulmak ve PageDown göndermek element.SendKeys(Keys.PageDown);benim için çalıştı.
Gokul

Sayfayı kaydırmamanız ve bazı öğelere anahtar göndermeye çalışırken oluşabilecek hataları işlemek için try / outside (Python) yan tümcesini kullanmamanız için Alt tuşunu kullanmanızı öneririm.
Alex K.

4

Deneyimlerime göre, Selenium Webdriver, sayfada birden fazla kaydırılabilir bölüm olduğunda (bu oldukça yaygın) otomatik olarak tıklandığında bir öğeye gitmiyor.

Ruby kullanıyorum ve benim AUT için, tıklama yöntemi aşağıdaki gibi yama yama vardı;

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' yöntemi WebElement sınıfında var olan bir yöntemdir.

Ruby kullanmıyor olabilirsiniz ama size bazı fikirler vermeliyiz.


Yukarıdakileri beyan module Capybara :: module Nodeettim native.location_once_scrolled_into_viewve sadece yerine aramak zorunda kaldım location_once_scrolled_into_view. Ayrıca kurtardım ::Selenium::WebDriver::Error::UnknownError, Firefox 44.0.2'de sık sık alıyorum. Ancak bu çözümü yeterince esnek bulmuyorum ve sonuçta <Element>.native.location_once_scrolled_into_viewçağrıları kabul testinin kendisine koydu , ardından hemen page.execute_script('window.scrollByPages(-1)')gerektiğinde.
Al Chou

Watir, Element#scroll_into_viewSelenyum'a delege olan bir metoda sahiptir location_once_scrolled_into_view. Ancak her ikisi de Selenyum'un varsayılan davranışından farklı bir şey yapmaz, böylece taşma öğeleri yine de tıklamaya çalıştığımız her şeyi engelleyebilir.
akostadinov

3

Bir öğeyi görünüme kaydırmak için Ruby komut dosyası aşağıdaki gibidir.

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

2

Bazen Selenyum ile kaydırma problemiyle de karşılaştım. Bu yüzden bunu başarmak için javaScriptExecuter kullandım.

Aşağı kaydırmak için:

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

Veya

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

Yukarı kaydırmak için:

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

Veya,

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

2

Diğer yanıtların çok huysuz olduğunu düşünüyorsanız, bu da öyle, ancak JavaScript enjeksiyonu dahil değil.

Düğme ekran kapalıyken kırılır ve kaydırılır, bu yüzden tekrar deneyin ... ¯ \ _ (ツ) _ / ¯

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

2

Bu, JavaScript ile tekrarlanan bir çözümdür, ancak öğe için eklenen bir eklentidir.

Aksi takdirde ElementNotVisibleException, eleman üzerinde bazı işlemler yapılıyorsa görünebilir.

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

?? <- ne demek?
Choi

1

Öğeyi kaydırmak için bu yolu kullandım ve tıklayın:

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

Benim durumumda scrollIntoView(false)çalıştı, ama scrollIntoView(true)olmadı. Ya çalışabilir , senaryonuza bağlıdır.
rsenna

Benim durumum tam tersi - doğru işler, yanlış başarısız, ama sadece tıklama kadarıyla. Yanlış için doğru kaydırır ve tercih ettiğim şey budur, ancak Selenium yine de tıklama için göremiyor. Gerçek kaydırma her şeyi çok yüksek kaydırır, ancak en azından çalışır.
Bill Hileman

Mümkün olduğunda kullanıcı gönderme anahtarları tıklama yerine girer - tarayıcı% 100 yakınlaştırmada değilse sorunları önler.
Zunair

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

1

Javascript kullanarak Web sayfaları ve Web sayfası - Selenium WebDriver'ı kaydırın sayfasını ziyaret etmek isteyebilirsiniz :

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'da da desteklendiğini hatırlıyorum. Karşılaşabileceğiniz belirli bir sorun var mı?
virusrocks

1

Kaydırma durumunun çoğunda bu kod çalışır.

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

1

JAVA

Öğe kullanma x ykonumuna ilerlemeyi deneyin ve JavascriptExecutorşu argümanla kullanın :"window.scrollBy(x, y)" .

İçe aktarma sonrasında:

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

Öncelikle x yöğeyi konumlandırmanız gerekir .

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

Selenium abd'nin varsayılan davranışı, öğenin görünüm penceresinin üst kısmında zar zor görüntülenmesi için kaydırılmasıdır. Ayrıca, tüm tarayıcılar aynı davranışa sahip değildir. Bu çok tatmin edici değil. Benim gibi tarayıcı testlerinizin videolarını kaydederseniz, istediğiniz şey öğenin görünüme kayması ve dikey olarak ortalanmasıdır .

İşte benim Java için çözüm:

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

Ve sonra, kaydırmak için şöyle diyorsunuz:

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 işlevi eksik ... Bir varsayımda hedef öğenin yüksekliğini alıyorsunuz
Shubham Jain

0

İşte Selenium için PHP webDriver ile nasıl yaparım. Selenium tek başına çalışan sunucu için çalışır 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();

Not: Element34 PHP-webdriver'ın özelleştirilmiş bir sürümünü kullanıyorum. Ancak çekirdekte herhangi bir değişiklik yok. Ben sadece "element" yerine "welement" kullanıyorum. Ancak söz konusu dava üzerinde hiçbir etkisi yoktur. Sürücü yazarı "hemen hemen tüm API çağrılarının WebDriver protokolünde tanımlananların doğrudan dönüştürülmesine izin vermek için" diyor. Yani diğer programlama dillerinde sorun yaşamamalısınız.

Sadece tıklamak kurulumumda çalışmaz. Tıklama yerine bir kaydırma yapacak, bu yüzden "location_in_view ()" çağırmadan iki kez tıklamak zorunda kaldı.

Not: Bu yöntem, tür düğmesinin girişi gibi görüntülenebilen öğeler için çalışır.

Şuna baksana: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location

JsonWireProtocol # açıklaması, _in_view konumu dahili bir yöntem olduğundan location + moveto kullanımını önerir.


0

Benim için çalışan bir şey, tarayıcı penceresinin altındaki bir öğede Browser.MoveMouseToElement yöntemini kullanmaktı. Mucizevi bir şekilde Internet Explorer, Firefox ve Chrome'da çalıştı.

Ben sadece daha az hileli hissettim çünkü JavaScript enjeksiyon tekniği seçti.


Bu hangi programlama dili?
akostadinov

0

ADF bileşenleri ile test yapıyorum ve tembel yükleme kullanılırsa kaydırma için ayrı bir komut olması gerekir. Nesne yüklenmezse ve Selenium kullanarak bulmaya çalışırsanız, Selenium öğe bulunamadı bir istisna atar.


0

Hiçbir şey işe yaramazsa, tıklamadan önce bunu deneyin:

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'da, aşağıdaki koddaki gibi JavaScript kullanarak kaydırma yapabiliriz:

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

"Elm.scrollTop" değişkenine istediğiniz bir değer atayabilirsiniz.


0

Bir çözüm:

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

Bu kod benim için çalışıyor:

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

Benim için çalışıyor. Dart WebDriver uygulamasının henüz bir eylemi yok.
Günter Zöchbauer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.