Berlawanan dengan apa yang disarankan oleh jawaban yang saat ini diterima , tidak ada yang spesifik untuk PhantomJS dalam hal perbedaan antara meminta WebDriver melakukan klik dan melakukannya dalam JavaScript.
Perbedaan
Perbedaan mendasar antara kedua metode ini adalah umum untuk semua browser dan dapat dijelaskan dengan cukup sederhana:
WebDriver: Ketika WebDriver melakukan klik, ia berusaha sebaik mungkin untuk mensimulasikan apa yang terjadi ketika pengguna nyata menggunakan browser. Misalkan Anda memiliki elemen A yang merupakan tombol yang mengatakan "Klik saya" dan elemen B yang merupakan div
elemen yang transparan tetapi memiliki dimensi dan zIndex
diatur sehingga sepenuhnya mencakup A. Kemudian Anda memberi tahu WebDriver untuk mengklik A. WebDriver akan mensimulasikan klik sehingga B menerima klik pertama . Mengapa? Karena B mencakup A, dan jika pengguna mencoba mengklik A, maka B akan mendapatkan acara terlebih dahulu. Apakah A akan mendapatkan event klik atau tidak tergantung pada bagaimana B menangani acara tersebut. Bagaimanapun, perilaku dengan WebDriver dalam kasus ini sama dengan ketika pengguna nyata mencoba mengklik A.
JavaScript: Sekarang, anggaplah Anda menggunakan JavaScript untuk melakukannya A.click()
. Metode mengklik ini tidak mereproduksi apa yang sebenarnya terjadi ketika pengguna mencoba mengklik A. JavaScript mengirimkan click
acara langsung ke A, dan B tidak akan mendapatkan peristiwa apa pun.
Mengapa Klik JavaScript Berfungsi Ketika Klik WebDriver Tidak?
Seperti yang saya sebutkan di atas WebDriver akan mencoba mensimulasikan sebaik mungkin apa yang terjadi ketika pengguna nyata menggunakan browser. Faktanya adalah bahwa DOM dapat berisi elemen-elemen yang tidak dapat berinteraksi dengan pengguna, dan WebDriver tidak akan mengizinkan Anda mengklik elemen ini. Selain kasus tumpang tindih yang saya sebutkan, ini juga mensyaratkan bahwa elemen tidak terlihat tidak dapat diklik. Kasus umum yang saya lihat dalam pertanyaan Stack Overflow adalah seseorang yang mencoba berinteraksi dengan elemen GUI yang sudah ada di DOM tetapi menjadi terlihat hanya ketika beberapa elemen lain telah dimanipulasi. Ini kadang-kadang terjadi dengan menu dropdown: Anda harus terlebih dahulu mengklik tombol yang memunculkan dropdown sebelum item menu dapat dipilih. Jika seseorang mencoba mengklik item menu sebelum menu terlihat,Jika orang tersebut kemudian mencoba melakukannya dengan JavaScript, itu akan berfungsi karena acara tersebut dikirim langsung ke elemen, terlepas dari visibilitasnya.
Kapan Anda Harus Menggunakan JavaScript untuk Mengklik?
Jika Anda menggunakan Selenium untuk menguji aplikasi , jawaban saya untuk pertanyaan ini "hampir tidak pernah". Pada umumnya, tes Selenium Anda harus mereproduksi apa yang akan dilakukan pengguna dengan browser. Mengambil contoh menu drop down: tes harus mengklik tombol yang memunculkan drop down pertama, dan kemudian klik pada item menu. Jika ada masalah dengan GUI karena tombolnya tidak terlihat, atau tombol gagal menampilkan item menu, atau yang serupa, maka pengujian Anda akan gagal dan Anda akan mendeteksi bug. Jika Anda menggunakan JavaScript untuk mengklik, Anda tidak akan dapat mendeteksi bug ini melalui pengujian otomatis.
Saya mengatakan "hampir tidak pernah" karena mungkin ada pengecualian di mana masuk akal untuk menggunakan JavaScript. Mereka seharusnya sangat langka.
Jika Anda menggunakan Selenium untuk mengikis situs , maka tidaklah penting untuk mencoba mereproduksi perilaku pengguna. Jadi menggunakan JavaScript untuk mem-bypass GUI tidak terlalu menjadi masalah.
click
atausendKeys
bekerja - tetapi tidak selalu. Tidak ada masalah penempatan atau pengecualian lain, test case tidak mengalami kemajuan lebih lanjut. Penebangan menunjukkan bahwa tindakan tersebut dilakukan. Terkadang menggunakan bantuanAction
. Jika saya mengklik elemen secara manual (setelah test case berhenti), semuanya bekerja dengan baik. Jadi kami beralih ke JS mentah pada kesempatan itu. Saya belum bekerja dengan AngularJS selama 2 tahun terakhir, jadi semuanya mungkin lebih baik sekarang.Klik yang dijalankan oleh driver mencoba mensimulasikan perilaku pengguna nyata sedekat mungkin sementara JavaScript
HTMLElement.click()
melakukan tindakan default untukclick
acara tersebut, bahkan jika elemen tersebut tidak dapat berinteraksi.Perbedaannya adalah:
Pengemudi memastikan bahwa elemen tersebut terlihat dengan menggulirnya ke tampilan dan memeriksa apakah elemen tersebut dapat berinteraksi .
Pengemudi akan meningkatkan kesalahan:
disabled
adalahtrue
)pointer-events
adalahnone
)JavaScript
HTMLElement.click()
akan selalu melakukan tindakan default atau paling tidak akan gagal jika elemen dinonaktifkan.Pengemudi diharapkan untuk membawa elemen ke dalam fokus jika dapat fokus .
JavaScript
HTMLElement.click()
tidak akan.Pengemudi diharapkan memancarkan semua peristiwa (mousemove, mousedown, mouseup, klik, ...) seperti layaknya pengguna sungguhan.
JavaScript
HTMLElement.click()
hanya memancarkanclick
acara. Halaman ini mungkin bergantung pada acara tambahan ini dan mungkin berperilaku berbeda jika tidak dipancarkan.Ini adalah acara yang dipancarkan oleh pengemudi untuk klik dengan Chrome:
Dan ini adalah acara yang dipancarkan dengan injeksi JavaScript:
Acara yang dipancarkan oleh JavaScript
.click()
tidak tepercaya dan tindakan default mungkin tidak dipanggil:https://developer.mozilla.org/en/docs/Web/API/Event/isTrusted
https://googlechrome.github.io/samples/event-istrusted/index.html
Perhatikan bahwa beberapa driver masih menghasilkan acara yang tidak dipercaya. Ini adalah kasus dengan PhantomJS pada versi 2.1.
Acara yang dipancarkan oleh JavaScript
.click()
tidak memiliki koordinat klik .Properti
clientX, clientY, screenX, screenY, layerX, layerY
diatur ke0
. Halaman mungkin bergantung pada mereka dan mungkin berperilaku berbeda.Mungkin ok untuk menggunakan JavaScript
.click()
untuk menghapus beberapa data, tetapi itu tidak dalam konteks pengujian. Itu mengalahkan tujuan pengujian karena tidak mensimulasikan perilaku pengguna. Jadi, jika klik dari driver gagal, maka pengguna nyata kemungkinan besar juga gagal melakukan klik yang sama dalam kondisi yang sama.Elemen yang ditargetkan belum terlihat / berinteraksi karena penundaan atau efek transisi.
Beberapa contoh :
https://developer.mozilla.org/fr/docs/Web (menu navigasi dropdown) http://materializecss.com/side-nav.html (bilah sisi dropdown)
Workarrounds:
Tambahkan pelayan untuk menunggu visibilitas, ukuran minimum atau posisi tetap:
Coba lagi untuk mengklik sampai berhasil:
Tambahkan penundaan yang cocok dengan durasi animasi / transisi:
Elemen yang ditargetkan berakhir dengan elemen mengambang setelah digulir ke tampilan:
Pengemudi secara otomatis menggulir elemen ke tampilan untuk membuatnya terlihat. Jika halaman berisi elemen mengambang / lengket (menu, iklan, footer, notifikasi, kebijakan cookie ..), elemen tersebut mungkin akan tertutup dan tidak lagi terlihat / berinteraksi.
Contoh: https://twitter.com/?lang=en
Penanganan masalah:
Atur ukuran jendela ke yang lebih besar untuk menghindari pengguliran atau elemen mengambang.
Pindahkan elemen dengan
Y
offset negatif lalu klik:Gulir elemen ke tengah jendela sebelum klik:
Sembunyikan elemen apung jika tidak dapat dihindari:
sumber
CATATAN: sebut saja 'klik' adalah klik pengguna akhir. 'js click' adalah klik melalui JS
Ada 2 kasus untuk ini terjadi:
I. Jika Anda menggunakan PhamtomJS
Maka ini adalah perilaku yang paling umum diketahui
PhantomJS
. Beberapa elemen terkadang tidak dapat diklik, misalnya<div>
. Ini karenaPhantomJS
ini asli dibuat untuk mensimulasikan mesin browser (seperti HTML + CSS awal -> komputasi CSS -> rendering). Tetapi itu tidak berarti berinteraksi dengan cara pengguna akhir (melihat, mengklik, menyeret). KarenaPhamtomJS
itu hanya didukung sebagian dengan interaksi pengguna akhir.MENGAPA JS KLIK BEKERJA? Adapun klik, mereka semua adalah klik berarti. Itu seperti pistol dengan 1 barel dan 2 pemicu . Satu dari viewport, satu dari JS. Karena
PhamtomJS
hebat dalam mensimulasikan mesin peramban, klik JS seharusnya bekerja dengan sempurna.II Penangan acara "klik" harus terikat dalam periode waktu yang buruk.
Sebagai contoh, kami mendapat
<div>
-> Kami melakukan beberapa perhitungan
-> lalu kita ikat acara klik ke
<div>
.-> Plus dengan beberapa pengkodean sudut yang buruk (mis. Tidak menangani siklus scope dengan benar)
Kita mungkin berakhir dengan hasil yang sama. Klik tidak akan berfungsi, karena WebdriverJS mencoba mengklik pada elemen ketika tidak memiliki pengendali event klik.
MENGAPA JS KLIK BEKERJA? Js klik seperti menyuntikkan js langsung ke browser. Mungkin dengan 2 cara,
Fist melalui konsol devtools (ya, WebdriverJS berkomunikasi dengan konsol devtools).
Kedua adalah menyuntikkan
<script>
tag langsung ke HTML.Untuk setiap browser, perilakunya akan berbeda. Tetapi bagaimanapun juga, metode ini lebih menyulitkan daripada mengklik tombol. Klik menggunakan apa yang sudah ada (klik pengguna akhir), klik saja akan melalui backdoor.
Dan untuk klik js akan tampak sebagai tugas yang tidak sinkron. Hal ini terkait dengan topik yang agak rumit tentang ' tugas asinkron peramban dan penjadwalan tugas CPU ' (baca beberapa waktu lalu tidak dapat menemukan artikel lagi). Singkatnya, ini sebagian besar akan menghasilkan js klik akan perlu menunggu siklus penjadwalan tugas CPU dan akan berjalan sedikit lebih lambat setelah pengikatan acara klik. (Anda bisa mengetahui kasus ini ketika Anda menemukan elemen kadang-kadang dapat diklik, kadang tidak.)
=> Seperti disebutkan di atas, keduanya berarti untuk satu tujuan, tetapi tentang menggunakan pintu masuk mana:
=> Untuk kinerja, sulit untuk mengatakan karena itu bergantung pada browser. Tetapi umumnya:
=> Kerugian:
PS jika Anda mencari solusi.
browser.wait()
( periksa ini untuk informasi lebih lanjut )(Saya ingin membuatnya singkat, tetapi berakhir dengan buruk. Apa pun yang berhubungan dengan teori rumit untuk dijelaskan ...)
sumber