Bagaimana cara memaksa Selenium WebDriver untuk mengklik elemen yang saat ini tidak terlihat?

99

Saya menggunakan Selenium 2 Java API dengan FirefoxDriver. Saat saya mengisi formulir, kotak centang ditambahkan ke halaman tergantung pada masukan formulir.

Saya ingin mensimulasikan klik pada kotak centang tersebut menggunakan Selenium. Elemen terlihat dan dapat digunakan di browser biasa tetapi, selenium menegaskan bahwa elemen tidak terlihat.

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

Bisakah saya memaksa selenium untuk mengabaikan keadaan elemen yang tidak terlihat? Bagaimana cara memaksa Selenium untuk berinteraksi dengan elemen yang tidak terlihat?

djondal
sumber
Browser apa yang Anda gunakan? Anda tidak dapat berinteraksi dengan elemen yang dinonaktifkan atau tidak terlihat karena pengguna akhir tidak akan dapat berinteraksi dengannya. Anda harus memberikan kode pengujian dan Sumber halaman jika Anda ingin saya mencoba dan mendiagnosis masalah.
Ardesco

Jawaban:

102

Selenium menentukan sebuah elemen terlihat atau tidak dengan kriteria berikut (gunakan pemeriksa DOM untuk menentukan css apa yang diterapkan ke elemen Anda, pastikan Anda melihat gaya yang dihitung):

  • visibilitas! = tersembunyi
  • display! = none (juga diperiksa terhadap setiap elemen induk)
  • opacity! = 0 (ini tidak dicentang untuk mengklik elemen)
  • tinggi dan lebar keduanya> 0
  • untuk sebuah masukan, tipe atribut! = tersembunyi

Elemen Anda cocok dengan salah satu kriteria tersebut. Jika Anda tidak memiliki kemampuan untuk mengubah gaya elemen, berikut adalah bagaimana Anda dapat melakukannya secara paksa dengan javascript (akan menganggap WebDriver karena Anda mengatakan Selenium2 API):

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

Tapi itu tidak akan mengaktifkan peristiwa javascript, jika Anda bergantung pada peristiwa perubahan untuk masukan itu Anda harus mengaktifkannya juga (banyak cara untuk melakukannya, termudah untuk menggunakan pustaka javascript apa pun yang dimuat di halaman itu).

Sumber untuk pemeriksaan visibilitas -

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

Spesifikasi WebDriver yang mendefinisikan ini -

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

Lukeis
sumber
1
Apakah Anda memiliki sumber (atau tautan kanonik) untuk daftar ketentuan?
mjs
2
Selama Anda dapat membaca Javascript, metode bot.dom.isShown adalah yang menentukan visibilitas: code.google.com/p/selenium/source/browse/trunk/javascript/atoms/…
lukeis
apa inputElement di sini. Saya menjalankan kode di bawah ini WebElement inputElement = driver.findElement (By.xpath (PASSWORD_PATH)); ((JavascriptExecutor) driver) .executeScript ("argumen [0] .checked = true;", inputElement); Tapi Tidak Ada Bantuan inputElement.sendKeys (kata sandi);
Deepak Goel
2
@NIleshSharma python memiliki metode execute_script langsung pada objek driver itu sendiri: driver.execute_script (...)
lukeis
1
Tautan sumber yang diposting oleh @TunaBum telah berubah menjadi code.google.com/p/selenium/source/browse/javascript/atoms/…
Shepmaster
27

Terkadang ini berarti ada beberapa elemen di halaman yang memiliki properti sama yang Anda coba telusuri dan Anda "berbicara dengan orang yang salah".

Jika elemen Anda tidak dapat diidentifikasi secara unik oleh: id atau: name (atau: class), ini bisa jadi rumit.

Kadang-kadang mencari elemen dengan: xpath akan membantu dan dalam beberapa kasus bahkan itu tidak praktis.

Dalam kasus tersebut, Anda mungkin harus mendapatkan semua elemen yang sesuai dengan kriteria Anda dan mereferensikan yang benar dengan indeks. Ini kotor, tapi berhasil.

Saya menggunakan Selenium / Watir dari aplikasi Ruby on Rails, jadi dalam kasus saya contohnya adalah:

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

Semoga ini membantu.

ranktrackerpro
sumber
menambahkan id ke elemen dom memperbaikinya untuk saya
naoru
Saya memiliki masalah yang sama dan menyesuaikan XPath sehingga dapat membedakan elemen unik melakukan trik.
JohnL
Saya memiliki masalah yang sama. Mengubah panggilan ke findElements () untuk menghitung kecocokan dan ada satu elemen yang cocok lagi. Terima kasih!
Aries
Begitu banyak ini untukku. SELALU pastikan kriteria pemilihan Anda cukup spesifik untuk elemen yang menurut Anda berinteraksi dengan Anda. Sering kali saya memiliki dua elemen yang berperan dan satu disembunyikan dan memberi saya kesalahan ini.
Chris
14

Saya memiliki masalah serupa, tetapi itu terkait dengan elemen yang tidak terlihat di viewport. Saya mengambil tangkapan layar dan menyadari jendela browser terlalu sempit dan elemen tidak dapat dilihat. Saya melakukan salah satunya dan berhasil:

driver.maximize_window()

Lihat: WebDriver.maximize_window ()

mynameistechno
sumber
7

Atau Anda dapat menggunakan Selenium Action Class untuk mensimulasikan interaksi pengguna - Misalnya

    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();
fil mihaylov
sumber
7

Ada juga kasus lain ketika elemen yang terlihat akan dikenali sebagai tidak terlihat:

  • Ketika Elemen CSS diubah
  • Ketika Elemen Induk dari Elemen diubah CSS

Untuk memeriksa apakah elemen yang Anda tidak ingin berinteraksi dengan CSS diubah, di CHROME lakukan ini:

  1. inspektur terbuka
  2. Temukan elemen yang menarik (atau lebih mungkin elemen induknya, seharusnya elemen div)
  3. Pilih tab 'Dihitung'
  4. jika ada parameter: webkit-transform: matrix (...) itu berarti elemen tersebut telah diubah CSS, dan mungkin tidak dikenali oleh selenium 2 sebagai elemen yang terlihat
justnpT
sumber
5

Tidak terlihatnya juga bisa karena waktu ketika elemen seharusnya muncul perlahan. Memaksa browser untuk menunggu sebentar mungkin membantu dalam kasus itu.

Lihat, misalnya, pertanyaan tentang membiarkan WebDriver menunggu hingga elemen ada .

avandeursen
sumber
2

Saya memiliki masalah yang sama dengan selenium 2 di internet explorer 9, tetapi perbaikan saya sangat aneh. Saya tidak dapat mengklik input di dalam formulir saya -> pengulangan selenium, mereka tidak terlihat.

Itu terjadi ketika formulir saya memiliki bayangan melengkung -> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects : dalam "Efek no. 2" yang konkret

Saya tidak tahu, mengapa & bagaimana solusi elemen semu ini menghentikan tes selenium, tetapi berhasil untuk saya.

Agoreddah
sumber
2

Anda tidak dapat memaksa mengakses / mengubah elemen yang biasanya tidak dapat diakses oleh pengguna, karena Selenium dirancang untuk meniru interaksi pengguna.

Jika kesalahan ini terjadi, periksa apakah:

  • elemen terlihat di viewport Anda, coba maksimalkan jendela saat ini yang digunakan webdriver (mis maximize() di node.js , maximize_window()dengan Python),
  • elemen Anda tidak muncul dua kali (di bawah selektor yang sama), dan Anda memilih yang salah,
  • jika elemen Anda tersembunyi, pertimbangkan untuk membuatnya terlihat,
  • jika Anda ingin mengakses / mengubah nilai elemen tersembunyi meskipun ada batasan, gunakan Javascript untuk itu (misalnya executeScript()di node.js , execute_script()dengan Python).
kenorb
sumber
1
Saya tidak tahu Selenium dirancang seketat ini. Tampaknya ini bukan alat otomatisasi dalam arti umum, lebih dari alat interaksi pengguna otomatis. Sedikit masuk akal kurasa. Terima kasih telah mengklarifikasi!
Daniel Lidström
1

Saya baru saja menyelesaikan kesalahan ini saat menggunakan kapibara di proyek ror dengan menambahkan:

Capybara.ignore_elements = true

kepada features/support/env.rb.

Zernel
sumber
1

Saya baru saja menyelesaikan kesalahan ini dengan menunggu properti tampilan elemen

waitFor() { element.displayed }
Suat Keskin
sumber
Dari semua jawaban di halaman ini, inilah yang memperbaiki masalah saya dengan dialog Bootstrap Modal. Terima kasih @Suat Keskin!
alastairs
1

Saya masuk ke pengecualian ElementNotVisibleException menggunakan selenium untuk tes fungsional di situs django dengan glyphicons bootstrap sebagai tautan di templat sebagai:

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

Selama pengujian fungsional saya, gaya bootstrap tidak dimuat, kemudian mencoba mengklik tautan seperti itu akan memunculkan ElementNotVisibleException. Saya berhasil membuatnya dapat diklik hanya dengan menambahkan spasi di tag, seperti itu:

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

Ada banyak jawaban bagus di halaman ini.

  1. Saya biasanya mulai dengan maksimalkan.window (), sebenarnya saya melakukan ini di Pabrik driver atau di mana pun Anda menginisialisasi driver Anda. Ini adalah sesuatu yang dilakukan secara default - selalu.
  2. Ini biasanya menunggu elemen karena javascript delay.

Keduanya dibahas dalam berbagai detail di atas. Jawaban yang tidak saya lihat adalah ScrollToElement. Sepertinya Anda sedang memproses daftar elemen, sementara memproses Anda membuat lebih banyak elemen, kotak centang. Ini dapat menyebabkan elemen dalam daftar Anda keluar dari halaman yang terlihat. Terkadang Anda dapat melihat elemen dengan mata telanjang tetapi Anda tidak bisa mengkliknya. Saat memproses daftar, Anda terkadang harus menyela pengguliran.

  • Tetapkan break point dan periksa untuk melihat apakah elemen yang Anda gunakan berada di tepi jendela, kanan atas / bawah / kiri. Kadang-kadang saat ini terjadi Anda tidak dapat mengaksesnya melalui selenium tetapi Anda dapat mengklik secara manual dengan mouse Anda.

Karena saya menjalankan ini, saya membuat PageScroll.java dan meletakkan skrip gulir saya di sana. Berikut adalah beberapa metode dari kelas ini:

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

lihat Scroll Element ke View dengan Selenium untuk contoh lainnya

mancocapac.dll
sumber
0

Jawaban yang diterima berhasil untuk saya. Di bawah ini adalah beberapa kode untuk menemukan elemen induk yang membuat Selenium berpikir bahwa itu tidak terlihat.

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

starmer
sumber
0

Untuk menambahkan butiran pasir saya di sini: jika sebuah elemen berada di belakang div tetap, itu akan dianggap tidak terlihat dan Anda tidak akan dapat mengkliknya; ini terjadi pada saya baru-baru ini dan saya menyelesaikannya dengan menjalankan skrip seperti yang disarankan di atas, yang tidak:

document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);
Fernando Gabrieli
sumber
Apa pencari lokasi di sini?
Anjana