Bagaimana cara mengatasi ambiguitas di Kapibara? Untuk beberapa alasan saya memerlukan link dengan nilai yang sama di halaman tetapi saya tidak dapat membuat pengujian karena saya mendapatkan error
Failure/Error: click_link("#tag1")
Capybara::Ambiguous:
Ambiguous match, found 2 elements matching link "#tag1"
Alasan mengapa saya tidak bisa menghindari ini adalah karena desainnya. Saya mencoba membuat ulang halaman twitter dengan tweet / tag di sebelah kanan dan tag di kiri halaman. Oleh karena itu, tidak dapat dihindari bahwa halaman link yang identik muncul di halaman yang sama.
ruby-on-rails-3
rspec
capybara
neilmarion.dll
sumber
sumber
Jawaban:
Solusi saya adalah
dari pada
sumber
first
seperti yang disarankan di atas, kecuali Anda benar-benar tahu apa yang Anda lakukan, kemungkinan besar akan menghasilkan spesifikasi yang cocok untuk Anda, tetapi gagal dalam rakitan CI atau pada mesin rekan.Perilaku kapibara seperti itu disengaja dan saya percaya itu tidak boleh diperbaiki seperti yang disarankan di sebagian besar jawaban lain.
Versi Capybara sebelum 2.0 mengembalikan elemen pertama alih-alih memunculkan pengecualian tetapi pengelola Capybara kemudian memutuskan bahwa itu adalah ide yang buruk dan lebih baik untuk meningkatkannya. Diputuskan bahwa dalam banyak situasi mengembalikan elemen pertama mengarah pada pengembalian elemen yang tidak diinginkan oleh pengembang untuk dikembalikan.
Jawaban yang paling disukai di sini merekomendasikan untuk digunakan
first
atauall
alih-alihfind
tetapi:all
danfirst
jangan menunggu sampai elemen dengan pelacak seperti itu akan muncul di halaman meskipunfind
menungguall(...).first
danfirst
tidak akan melindungi Anda dari situasi yang di masa mendatang elemen lain dengan pelacak seperti itu dapat muncul di halaman dan akibatnya Anda mungkin menemukan elemen yang salahJadi disarankan untuk memilih pencari lokasi lain yang tidak terlalu ambigu : misalnya pilih elemen berdasarkan id, kelas atau pencari lokasi css / xpath lain sehingga hanya satu elemen yang akan cocok dengannya.
Sebagai catatan, berikut adalah beberapa pencari lokasi yang biasanya saya anggap berguna saat menyelesaikan ambiguitas:
find('ul > li:first-child')
Ini lebih berguna daripada
first('ul > li')
menunggu sampai pertama kalili
muncul di halaman.click_link('Create Account', match: :first)
Ini lebih baik daripada
first(:link, 'Create Account').click
menunggu sampai setidaknya satu link Buat Akun akan muncul di halaman. Namun saya yakin lebih baik memilih pelacak unik yang tidak muncul di halaman dua kali.fill_in('Password', with: 'secret', exact: true)
exact: true
memberi tahu Kapibara untuk hanya menemukan yang sama persis, yaitu tidak menemukan "Konfirmasi Kata Sandi"sumber
Solusi di atas berfungsi dengan baik tetapi bagi mereka yang penasaran Anda juga dapat menggunakan sintaks berikut.
Anda dapat menemukan informasi lebih lanjut di sini:
http://taimoorchangaizpucitian.wordpress.com/2013/09/06/capybara-click-link-different-cases-and-solutions/
sumber
JAWABAN BARU:
Anda bisa mencoba sesuatu seperti
Mungkin ada cara untuk melakukan ini yang memanfaatkan sintaks Capybara yang tersedia dengan lebih baik - sesuatu di sepanjang garis
all("a[text='#tag1']").first.click
tetapi saya tidak dapat memikirkan sintaks yang benar begitu saja dan saya tidak dapat menemukan dokumentasi yang sesuai. Yang mengatakan itu sedikit situasi yang aneh untuk memulai dengan, memiliki dua<a>
tag dengan yang samaid
,class
, dan teks. Adakah kemungkinan mereka adalah turunan dari div yang berbeda, karena Anda kemudian dapat melakukanfind
within
segmen DOM yang sesuai. (Ini akan membantu untuk melihat sedikit dari sumber HTML Anda).JAWABAN LAMA: (saat saya pikir '# tag1' berarti elemen tersebut memiliki
id
"tag1")Manakah dari link yang ingin Anda klik? Jika itu yang pertama (atau tidak masalah), Anda bisa melakukannya
Jika tidak, Anda bisa melakukannya
untuk mengklik yang kedua.
sumber
find('#tag1')
berarti Anda hanya ingin menemukan satu elemen dengan idtag1
. Pengecualian dimunculkan karena ada beberapa elemen dengan idtag1
di halamanall(:xpath, '//a[text()="#tag1"]').first.click
.Anda dapat memastikan bahwa Anda menemukan yang pertama menggunakan
match
:Namun yang terpenting, Anda mungkin tidak ingin melakukan ini , karena ini akan mengarah pada pengujian rapuh yang mengabaikan bau kode keluaran duplikat, yang pada gilirannya mengarah ke positif palsu yang tetap berfungsi ketika seharusnya gagal, karena Anda menghapus satu pencocokan elemen tetapi tes dengan senang hati menemukan yang lain.
Taruhan yang lebih baik adalah menggunakan
within
:Ini memastikan bahwa Anda menemukan elemen yang Anda harapkan untuk ditemukan, sambil tetap memanfaatkan kemampuan tunggu otomatis dan coba ulang otomatis dari Capybara (yang hilang jika Anda menggunakannya
find('.selector').click
), dan itu membuatnya lebih jelas apa maksudnya.sumber
Untuk menambah badan pengetahuan yang ada di sini:
Untuk pengujian JS, Capybara harus menjaga dua utas (satu untuk RSpec, satu untuk Rails) dan proses kedua (browser) selaras. Ini dilakukan dengan menunggu (hingga waktu tunggu maksimum yang dikonfigurasi) di kebanyakan matcher dan metode pencarian node.
Kapibara juga memiliki metode yang tidak perlu menunggu
Node#all
. Menggunakannya seperti memberi tahu spesifikasi Anda bahwa Anda ingin mereka sesekali gagal.Jawaban yang diterima menyarankan
page.first('selector')
. Ini tidak diinginkan, setidaknya untuk spesifikasi JS, karenaNode#first
menggunakanNode#all
.Yang mengatakan,
Node#first
akan menunggu jika Anda mengkonfigurasi kapibara seperti ini:Opsi ini telah ditambahkan di Capybara 2.5.0 dan salah secara default.
Seperti yang disebutkan Andrei, Anda sebaiknya menggunakan
atau ubah pemilih Anda. Keduanya akan bekerja dengan baik terlepas dari konfigurasi atau drivernya.
Untuk lebih memperumit masalah, di versi lama Kapibara (atau dengan opsi konfigurasi diaktifkan),
#find
dengan senang hati akan mengabaikan ambiguitas dan hanya mengembalikan pemilih pencocokan pertama. Ini juga tidak bagus, karena membuat spesifikasi Anda kurang eksplisit, yang menurut saya adalah mengapa tidak ada lagi perilaku default. Saya akan mengabaikan spesifikasinya karena mereka sudah dibahas di atas.Sumber daya lainnya:
sumber
Karena postingan ini , Anda dapat memperbaikinya melalui opsi "cocok":
sumber
Saat mempertimbangkan semua opsi di atas, Anda juga dapat mencobanya
Jika Anda menggunakan mentimun, Anda juga bisa mengikuti ini
Anda dapat mengirimkan teks sebagai parameter dari langkah-langkah skenario yang dapat menjadi langkah umum untuk digunakan kembali
Sesuatu seperti
When a user clicks on "text" link
Dan dalam definisi langkah
When(/^(?:user) clicks on "([^"]*)" (?:link)$/) do |text|
Dengan cara ini, Anda dapat menggunakan kembali langkah yang sama dengan meminimalkan baris kode dan akan mudah untuk menulis skenario ketimun baru
sumber
Untuk menghindari kesalahan ambigu pada mentimun.
Solusi 1
Solusi 2
sumber