Selenium WebDriver'ı şu anda görünür olmayan öğeye tıklamaya nasıl zorlayabilirim?


99

FirefoxDriver ile Selenium 2 Java API kullanıyorum. Bir formu doldurduğumda, form girişlerine bağlı olarak sayfaya onay kutuları ekleniyor.

Selenium kullanarak bu onay kutularına bir tıklamayı simüle etmek istiyorum. Öğe, normal bir tarayıcıda görülebilir ve kullanılabilir ancak selenyum, öğelerin görünmediğini iddia eder.

"Element is not currently visible and so may not be interacted with"

Selenyum, elementlerin görünmeyen durumunu görmezden gelmeye zorlayabilir miyim? Selenium'u görünmeyen öğeyle etkileşime girmeye nasıl zorlayabilirim?


Hangi tarayıcıyı kullanıyorsunuz? Devre dışı bırakılan veya görünmeyen öğelerle etkileşim kuramazsınız çünkü bir son kullanıcı onlarla etkileşime geçemez. Sorunu teşhis etmemi istiyorsanız, test kodunuzu ve Sayfa kaynağınızı sağlamanız gerekir.
Ardesco

Yanıtlar:


102

Selenium, bir öğenin görünür olup olmadığını aşağıdaki kriterlere göre belirler (öğenize hangi css'nin geçerli olduğunu belirlemek için bir DOM denetçisi kullanın, hesaplanmış stile baktığınızdan emin olun):

  • görünürlük! = gizli
  • display! = none (ayrıca her ana öğeye karşı kontrol edilir)
  • opaklık! = 0 (bu, bir öğeyi tıklamak için kontrol edilmez)
  • yükseklik ve genişliğin ikisi de> 0
  • bir girdi için öznitelik türü! = gizli

Öğeniz bu kriterlerden biriyle eşleşiyor. Öğenin stilini değiştirme yeteneğiniz yoksa, işte bunu javascript ile nasıl zorla yapabilirsiniz (Selenium2 API dediğinizden WebDriver varsayılacaktır):

((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);

Ancak bu, bir javascript olayını tetiklemez, eğer o giriş için değişiklik olayına bağlıysanız, onu da ateşlemeniz gerekir (bunu yapmanın birçok yolu, o sayfada yüklü olan javascript kitaplığını kullanmak en kolay olanıdır).

Görünürlük kontrolünün kaynağı -

https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577

Bunu tanımlayan WebDriver belirtimi -

https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#widl-WebElement-isDisplayed-boolean


1
Koşulların listesi için bir kaynağınız (veya kanonik bağlantınız) var mı?
mjs

2
Javascript okuyabildiğiniz sürece, bot.dom.isShown yöntemi görünürlüğü belirleyen şeydir: code.google.com/p/selenium/source/browse/trunk/javascript/atoms/…
lukeis

burada inputElement nedir. Aşağıdaki kodu çalıştırıyorum WebElement inputElement = driver.findElement (By.xpath (PASSWORD_PATH)); ((JavascriptExecutor) sürücüsü) .executeScript ("arguments [0] .checked = true;", inputElement); Ama Yardım yok inputElement.sendKeys (şifre);
Deepak Goel

2
@NIleshSharma python, execute_script yöntemine doğrudan sürücü nesnesinin kendisinde sahiptir: driver.execute_script (...)
lukeis

1
@TunaBum tarafından yayınlanan kaynak bağlantısı, code.google.com/p/selenium/source/browse/javascript/atoms/… olarak
Shepmaster

27

Bazen bu, bir sayfada aramaya çalıştığınız aynı özelliğe sahip birden çok öğe olduğu ve "yanlış olanla konuştuğunuz" anlamına gelir.

Öğeniz: id veya: name (veya: class) ile benzersiz bir şekilde tanımlanamıyorsa, aldatıcı olabilir.

Bazen elementi: xpath ile aramak yardımcı olacaktır ve bazı durumlarda bu bile pratik değildir.

Bu durumlarda, kriterlerinize uyan tüm unsurları almanız ve indekste doğru olanı referans almanız gerekebilir. Kirli ama işe yarıyor.

Ruby on Rails uygulamasından Selenium / Watir kullanıyorum, bu nedenle benim durumumda örnek şöyle olacaktır:

browser = Watir::Browser.new(:firefox, :profile => "default")       
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click

Bu yardımcı olur umarım.


dom öğesine bir kimlik eklemek benim için
sorunu çözdü

Aynı sorunu yaşadım ve XPath'i benzersiz bir öğeyi ayırt edebilmesi için ayarladım, hile yaptı.
JohnL

Ben de aynı sorunu yaşadım. Eşleşmeleri saymak için findElements () çağrısı değiştirildi ve eşleşen bir öğe daha vardı. Teşekkürler!
Koç

Bu benim için çok fazla. HER ZAMAN seçim kriterlerinizin etkileşim kurduğunuzu düşündüğünüz öğeye yeterince spesifik olduğundan emin olun. Çoğu zaman oyunda iki öğe oldu ve biri gizlendi ve bana bu hatayı veriyor.
Chris

14

Benzer bir sorun yaşadım, ancak öğenin görüntü alanında görünmemesiyle ilgiliydi. Bir ekran görüntüsü aldım ve tarayıcı penceresinin çok dar olduğunu ve öğenin görülemediğini fark ettim. Bunlardan birini yaptım ve işe yaradı:

driver.maximize_window()

Bakınız: WebDriver.maximize_window ()


7

Veya kullanıcı etkileşimini simüle etmek için Selenium Action Class kullanabilirsiniz - Örneğin

    WebDriver = new FirefoxDriver();

    WebElement menu = driver.findElement(By.xpath("")); // the triger event element

    Actions build = new Actions(driver); // heare you state ActionBuider
    build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
    WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
    m2m.click();

7

Ayrıca, görünür öğenin görünmez olarak tanınacağı başka bir durum daha vardır:

  • Öğe CSS dönüştürüldüğünde
  • Öğenin Üst Öğesi CSS'ye dönüştürüldüğünde

Etkileşimde bulunmayacağınız öğenin CSS dönüştürülmüş olup olmadığını kontrol etmek için CHROME'da şunu yapın:

  1. açık müfettiş
  2. İlginç öğe bulun (veya daha büyük olasılıkla ana öğesi, sözde div öğesi)
  3. "Hesaplanan" sekmesini seçin
  4. Bir parametre varsa: webkit-transform: matrix (...) bu, öğenin CSS'ye dönüştürüldüğü anlamına gelir ve selenyum 2 tarafından görünür bir öğe olarak tanınmayabilir


2

İnternet explorer 9'da selenyum 2 ile aynı sorunu yaşadım, ancak düzeltmem gerçekten garip. Formumdaki girdileri tıklayamadım -> selenyum tekrarları, görünür değil.

Formumda eğri gölgeler olduğunda ortaya çıktı -> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects : betonda "Efekt no. 2"

Bu sözde element çözümünün selenyum testlerini neden ve nasıl durdurduğu hakkında hiçbir fikrim yok, ama benim için işe yarıyor.


2

Selenium kullanıcı etkileşimini taklit etmek üzere tasarlandığından, kullanıcının normalde erişemediği öğeye erişimi / değiştirmeyi zorlayamazsınız.

Bu hata meydana gelirse, şunları kontrol edin:

  • öğesi görüntü alanınızda görünürse, webdriver'ın kullandığı mevcut pencereyi büyütmeyi deneyin (ör maximize(). node.js'de , maximize_window()Python'da),
  • öğeniz iki kez görünmüyor (aynı seçici altında) ve yanlış olanı seçiyorsunuz,
  • öğeniz gizliyse, onu görünür kılmayı düşünün,
  • Sınırlamaya rağmen gizli elemanın değerine erişmek / değiştirmek isterseniz, bunun için Javascript kullanın (örn executeScript(). node.js'de , execute_script()Python'da).

1
Selenium'un bu kadar katı olması için tasarlandığını bilmiyordum. Görünüşe göre, genel anlamda gerçekten bir otomasyon aracı değil, daha çok otomatik bir kullanıcı etkileşimi aracı. Sanırım biraz mantıklı. Açıkladığınız için teşekkürler!
Daniel Lidström

1

Ben sadece bu hatayı ror projesinde capybara kullanırken ekleyerek çözüyorum:

Capybara.ignore_elements = true

için features/support/env.rb.


1

Bu hatayı sadece eleman görüntüleme özelliğini bekleyerek çözüyorum

waitFor() { element.displayed }

Bu sayfadaki tüm cevaplar arasında, Bootstrap Kalıcı iletişim kutusuyla ilgili sorunumu çözen şey buydu. Teşekkürler @ Suat Keskin!
alastairs

1

Şablonlarda aşağıdaki gibi önyükleme glificonları ile bir django sitesinde işlevsel testler için selenyum kullanarak ElementNotVisibleException istisnasına giriyorum:

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>

İşlevsel testlerim sırasında, önyükleme stili yüklenmedi, daha sonra bu tür bağlantılara tıklamaya çalışmak ElementNotVisibleException'ı artıracak. Etikete bir boşluk ekleyerek tıklanabilir hale getirmeyi başarıyorum , örneğin:

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger">&nbsp;</span></a>

1

Bu sayfada pek çok iyi cevap var.

  1. Genelde maximize.window () ile başlarım, aslında bunu sürücü fabrikasında veya sürücünüzü nerede başlatırsanız başlatırım. Bu, varsayılan olarak yapılan bir şeydir - her zaman.
  2. Bazı javascript gecikmeleri nedeniyle genellikle öğe için bekleme.

Her ikisi de yukarıda çeşitli ayrıntılarda tartışılmıştır. Görmediğim cevap ScrollToElement idi. Görünüşe göre bir öğe listesini işliyorsunuz, işlerken daha fazla öğe, onay kutusu oluşturuyorsunuz. Bu, listenizdeki öğelerin görünen sayfadan çıkmasına neden olabilir. Bazen öğeyi çıplak gözle görebilirsiniz, ancak üzerine tıklayamazsınız. Listeleri işlerken bazen kaydırmaya müdahale etmeniz gerekir.

  • Bir kırılma noktası belirleyin ve kullandığınız öğenin pencere kenarında, üst / alt sağ / solda olup olmadığını kontrol edin. Bazen bu durumda selenyum yoluyla ona ulaşamazsınız, ancak farenizle manuel olarak tıklayabilirsiniz.

Bunun üzerinden geçtiğim için bir PageScroll.java oluşturdum ve kaydırma komut dosyalarımı oraya koydum. İşte bu sınıftaki yöntemlerden birkaçı:

public static void scrollToTop(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0,0)");
    }

    public static void scrollToBottom(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0, document.body.scrollHeight)");
    }

    public static void scrollToElementTop(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(true);", element);
    }

    public static void scrollToElementBottom(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(false);", element);
    }

Daha fazla örnek için Selenium ile Öğeyi Görünüme Kaydırma konusuna bakın


0

Kabul edilen cevap benim için çalıştı. Aşağıda, Selenium'un görünür olmadığını düşünmesini sağlayan ana öğeyi bulmak için bazı kodlar var.

function getStyles(element){
	
	computedStyle = window.getComputedStyle(element);

	if(computedStyle.opacity === 0
	|| computedStyle.display === "none"
	|| computedStyle.visibility === "hidden"
	|| (computedStyle.height < 0 && computedStyle.height < 0)
	|| element.type === "hidden") {
		console.log("Found an element that Selenium will consider to not be visible")
		console.log(element);
		console.log("opacity: " + computedStyle.opacity);
		console.log("display: " + computedStyle.display);
		console.log("visibility: " + computedStyle.visibility);
		console.log("height: " + computedStyle.height);
		console.log("width: " + computedStyle.width);
	}

	if(element.parentElement){
		getStyles(element.parentElement);
	}
}

getStyles(document.getElementById('REPLACE WITH THE ID OF THE ELEMENT YOU THINK IS VISIBLE BUT SELENIUM CAN NOT FIND'));


0

Buraya kum tanesini eklemek için: Bir öğe sabit bir div'in arkasında bulunuyorsa, görünmez olarak kabul edilecek ve onu tıklayamayacaksınız; bu son zamanlarda başıma geldi ve yukarıda önerildiği gibi bir komut dosyası çalıştırarak çözdüm, bu da:

document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);

Buradaki yer bulucu nedir?
Anjana
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.