ক্যাপিবারা অ্যামবিগুইটি রেজোলিউশন


97

ক্যাপিবারাতে আমি কীভাবে অস্পষ্টতা সমাধান করব? কোনও কারণে আমার একটি পৃষ্ঠায় একই মানগুলির সাথে লিঙ্কগুলি প্রয়োজন তবে ত্রুটি হওয়ার পরে আমি কোনও পরীক্ষা তৈরি করতে পারি না

Failure/Error: click_link("#tag1")
     Capybara::Ambiguous:
       Ambiguous match, found 2 elements matching link "#tag1"

আমি কেন এড়াতে পারি না তার কারণ হ'ল ডিজাইন। আমি ডানদিকে টুইটার / ট্যাগ এবং পৃষ্ঠার বামে ট্যাগ সহ টুইটার পৃষ্ঠাটি পুনরায় তৈরি করার চেষ্টা করছি। সুতরাং এটি অনিবার্য হবে যে অভিন্ন লিঙ্কগুলি পৃষ্ঠা একই পৃষ্ঠায় প্রদর্শিত হবে।


আপনি কিছু কোড পোস্ট করতে পারেন?
হিনা হুসেন

8
আপনার পৃষ্ঠায় দুটি উপাদানকে একই আইডি বরাদ্দ করা উচিত নয়। যদি আপনার অভিন্ন লিঙ্ক থাকে, তবে উপাদানগুলিকে কোনও আইডি বরাদ্দ করবেন না, পরিবর্তে একটি ক্লাস ব্যবহার করুন।
ক্রিস সালজবার্গ

উত্তর:


147

আমার সমাধানটি হ'ল

first(:link, link).click

পরিবর্তে

click_link(link)

6
এটি ক্যাপাইবার আপগ্রেড গাইডে বিস্তারিত রয়েছে আপনি যদি এই সমস্যাটি পান তবে আপনাকে দরকারী মনে হতে পারে।
রিচি

4
ক্যাপাইবার ২.০ হিসাবে আপনি এটি না করে এটি করবেন না। নীচে @ অ্যান্ডির উত্তর এবং উপরে লিঙ্ক করা আপগ্রেড গাইডে দ্ব্যর্থহীন ম্যাচের ব্যাখ্যা দেখুন।
জিম

4
বিশেষত, কেবলমাত্র ন্যূনতম প্রয়োজনীয় সময় অপেক্ষা করার সময় ক্যাপিবারা ২.০ এর স্পেসিংগুলি পৃথক প্রক্রিয়াজাতকরণের গতিগুলির মেশিনগুলিতে ধারাবাহিকভাবে পাস বা ধারাবাহিকভাবে ব্যর্থ হয় তা নিশ্চিত করার জন্য বুদ্ধিমান অপেক্ষার যুক্তি রয়েছে। firstউপরে প্রস্তাবিত হিসাবে ব্যবহার করা, আপনি কী করছেন তা পুরোপুরি না জানলে আপনি সম্ভবত এমন চশমা তৈরি করতে পারেন যা আপনার জন্য পাস করে তবে সিআই বিল্ডে বা সহকর্মীর মেশিনে ব্যর্থ হয়।
জিম

4
একটি ভাল আলোচনার জন্য দেখুন: robots.thoughtbot.com/…
জিম

74

ক্যাপিবার এই জাতীয় আচরণ ইচ্ছাকৃত এবং আমি বিশ্বাস করি এটি অন্যান্য বেশিরভাগ উত্তরের পরামর্শ অনুসারে ঠিক করা উচিত নয়।

২.০ এর আগে ক্যাপাইবার সংস্করণগুলি ব্যতিক্রম উত্থাপনের পরিবর্তে প্রথম উপাদানটি ফেরত দেয় তবে পরে ক্যাপিবারার রক্ষণাবেক্ষণকারীরা সিদ্ধান্ত নেন যে এটি একটি খারাপ ধারণা এবং এটি উত্থাপন করা আরও ভাল। এটি স্থির হয়েছিল যে অনেক পরিস্থিতিতে প্রথম উপাদানটি ফিরে আসার ফলে যে উপাদানটি বিকাশকারী ফিরে আসতে চায় তা ফিরে আসে না।

এখানে সর্বাধিক আপত্তিযুক্ত উত্তরগুলি ব্যবহারের পরিবর্তে firstবা এর allপরিবর্তে সুপারিশ করবে find:

  1. allএবং firstএই ধরনের লোকেটার সঙ্গে উপাদান পর্যন্ত অপেক্ষা করবেন না যদিও পৃষ্ঠায় উপস্থিত হবে findঅপেক্ষার করে
  2. all(...).firstএবং firstআপনাকে এমন পরিস্থিতি থেকে রক্ষা করবে না যে ভবিষ্যতে এই ধরণের লোকেটার সহ অন্য কোনও উপাদান পৃষ্ঠাতে উপস্থিত হতে পারে এবং ফলস্বরূপ আপনি ভুল উপাদান খুঁজে পেতে পারেন

সুতরাং এটির জন্য অন্যটি, কম অস্পষ্ট লোকেটার বেছে নেওয়ার পরামর্শ দেওয়া হয়েছে: উদাহরণস্বরূপ আইডি, শ্রেণি বা অন্যান্য সিএসএস / এক্সপাথ লোকেটার দ্বারা উপাদান নির্বাচন করুন যাতে কেবল একটি উপাদান এর সাথে মেলে।


এখানে একটি নোট হিসাবে কিছু লোকেশন রয়েছে যা আমি সাধারণত অস্পষ্টতার সমাধান করার সময় দরকারী বলে মনে করি:

  • find('ul > li:first-child')

    এটি পৃষ্ঠায় প্রদর্শিত হবে first('ul > li')যতক্ষণ না অপেক্ষা করা অপেক্ষা এটি আরও কার্যকর li

  • click_link('Create Account', match: :first)

    first(:link, 'Create Account').clickপৃষ্ঠায় কমপক্ষে একটি তৈরি অ্যাকাউন্ট লিঙ্ক উপস্থিত না হওয়া পর্যন্ত এটি অপেক্ষা করা থেকে ভাল । তবে আমি বিশ্বাস করি যে অনন্য লোকেটার চয়ন করা ভাল যা পৃষ্ঠায় দু'বার প্রদর্শিত হবে না।

  • fill_in('Password', with: 'secret', exact: true)

    exact: true ক্যাপিবারা কে কেবল সঠিক মিল খুঁজে পেতে বলে, "পাসওয়ার্ড কনফার্মেশন" খুঁজে না


7
এটি শীর্ষ উত্তর হওয়া উচিত। সর্বদা এমন একটি নির্বাচক ব্যবহার করার চেষ্টা করুন যা ক্যাপিবারায় অন্তর্নির্মিত অপেক্ষার ক্ষমতা ব্যবহার করবে।
tgf

ধন্যবাদ আমি ব্যবহার করার চেষ্টা করেছি: প্রথম কিন্তু বুঝতে পেরেছি যে কেবল jQuery এ কাজ করে। আমি যা খুঁজছিলাম তা হ'ল: প্রথম সন্তান
ওভারলোড 119

26

উপরের সমাধানটি দুর্দান্ত কাজ করে তবে যারা আগ্রহী তাদের জন্য আপনি নীচের বাক্য গঠনটিও ব্যবহার করতে পারেন।

click_link(link_name, match: :first)

আপনি এখানে আরও তথ্য পেতে পারেন:

http://taimoorchangaizpucitian.wordpress.com/2013/09/06/capybara-click-link-different-cases-and-solutions/


24

নতুন উত্তর:

আপনি যেমন কিছু চেষ্টা করতে পারেন

all('a').select {|elt| elt.text == "#tag1" }.first.click

এটি করার একটি উপায় থাকতে পারে যা উপলভ্য ক্যাপিবারা সিনট্যাক্সটির আরও ভাল ব্যবহার করে - যা কিছু ঠিক আছে all("a[text='#tag1']").first.clickতবে আমি সঠিক সিনট্যাক্সটি হাতছাড়া করতে পারি না এবং উপযুক্ত ডকুমেন্টেশন খুঁজে পাই না। যে বলেন, এটি একটি অদ্ভুত অবস্থা একটি বিট দিয়ে শুরু করতে, দুই থাকার এর <a>একই সঙ্গে ট্যাগ id, classএবং পাঠ্য। তারা কি আলাদা আলাদা ডিভের সন্তান হওয়ার কোনও সুযোগ আছে, যেহেতু আপনি তখন আপনার ডিওএমের find withinউপযুক্ত বিভাগটি করতে পারেন do (এটি আপনার HTML উত্সটি কিছুটা দেখতে সহায়তা করবে)।


পুরানো উত্তর: (যেখানে আমি ভেবেছিলাম '# ট্যাগ 1' অর্থ উপাদানটির id"ট্যাগ 1" ছিল )

আপনি কোন লিঙ্কে ক্লিক করতে চান? যদি এটি প্রথম (বা এটি কোনও ব্যাপার না) তবে আপনি এটি করতে পারেন

find('#tag1').click

অন্যথায় আপনি করতে পারেন

all('#tag1')[1].click

দ্বিতীয়টি ক্লিক করতে।


প্রথমটির সমাধানটি সম্ভবত কাজ হতে পারে তবে এখন সমস্যাটি হ'ল এটি সম্ভবত কোনও সিএসএস আইডি --------- ব্যর্থতা / ত্রুটি: সন্ধান করুন ('# ট্যাগ1') ক্লিক করুন # বা সমস্ত ক্লিক করুন ('# ট্যাগ 1 ') [0]। ক্যাপিবারা ক্লিক করুন :: এলিমেন্টনোটফাউন্ড: সিএসএস "# ট্যাগ
নীলমারিয়ান

find('#tag1')এর অর্থ হ'ল আপনি আইডি সহ একটি মাত্র উপাদান সন্ধান করতে চান tag1tag1পৃষ্ঠায় আইডি সহ বেশ কয়েকটি উপাদান রয়েছে বলে ব্যতিক্রম উত্থাপিত হয়েছিল
আন্দ্রেই বোতালভ

আপনি করতে পারেন all(:xpath, '//a[text()="#tag1"]').first.click
শুহেই কাগওয়া

9

আপনি নিশ্চিত করতে পারেন যে আপনি প্রথমটি ব্যবহার করে খুঁজে পেয়েছেন match:

find('.selector', match: :first).click

তবে গুরুত্বপূর্ণ, আপনি সম্ভবত এটি করতে চাইবেন না , কারণ এটি ভঙ্গুর পরীক্ষায় নেতৃত্ব দেবে যা সদৃশ-আউটপুট কোড গন্ধকে উপেক্ষা করে, যা ফলস্বরূপ মিথ্যা ইতিবাচক দিকে পরিচালিত করে যেগুলি ব্যর্থ হওয়া উচিত ছিল, কারণ আপনি একটি ম্যাচ সরিয়েছেন উপাদান কিন্তু পরীক্ষা সুখে অন্য এক খুঁজে।

আরও ভাল বাজি ব্যবহার করা হয় within:

within('#sidebar') do
  find('.selector).click
end

এটি নিশ্চিত করে যে আপনি ক্যাপিবারার স্বতঃ-অপেক্ষা এবং স্বতঃ-পুনরায় চেষ্টা করার ক্ষমতাটি ব্যবহার করার সময় আপনি যে উপাদানটি খুঁজে পাওয়ার প্রত্যাশা করছেন তা খুঁজে পেয়েছেন (যা আপনি যদি ব্যবহার করেন তবে আপনি হারাবেন find('.selector').click) এবং উদ্দেশ্যটি কী তা তা আরও স্পষ্ট করে তোলে।


7

বিদ্যমান জ্ঞানের এখানে যোগ করতে:

জেএস পরীক্ষার জন্য ক্যাপাইবারাকে দুটি থ্রেড রাখতে হবে (একটি আরএসপেকের জন্য, একটি রিলের জন্য) এবং একটি দ্বিতীয় প্রক্রিয়া (ব্রাউজার) সিঙ্কে রাখতে হবে। এটি বেশিরভাগ ম্যাথার এবং নোড সন্ধানের পদ্ধতিগুলিতে অপেক্ষা করে (কনফিগার হওয়া সর্বাধিক অপেক্ষা সময়ের অবধি) এটি করে।

ক্যাপিবারাতে এমন পদ্ধতিও রয়েছে যা প্রাথমিকভাবে অপেক্ষা করে না Node#all। এগুলি ব্যবহার করা আপনার চশমাগুলি বলার মতো যা আপনি চাইবেন যে তারা মাঝেমধ্যে ব্যর্থ হয়।

গৃহীত উত্তর প্রস্তাব দেয় page.first('selector')। এটি অনাকাঙ্ক্ষিত, কমপক্ষে জেএস স্পেসের জন্য, কারণ Node#firstব্যবহারNode#all

এটি বলেছিল, Node#first আপনি যদি ক্যাপিবারাটিকে এমনভাবে কনফিগার করেন তবে অপেক্ষা করবেন :

# rails_helper.rb
Capybara.wait_on_first_by_default = true

এই বিকল্পটি ক্যাপাইবার 2.5.0.0 এ যুক্ত হয়েছিল এবং এটি ডিফল্টরূপে মিথ্যা।

আন্দ্রেই যেমন উল্লেখ করেছেন, আপনার পরিবর্তে এটি ব্যবহার করা উচিত

find('selector', match: :first)

বা আপনার নির্বাচক পরিবর্তন করুন। হয় কনফিগার বা ড্রাইভার নির্বিশেষে ভাল কাজ করবে।

জিনিসগুলিকে আরও জটিল করার জন্য ক্যাপাইবারার পুরানো সংস্করণগুলিতে (বা কোনও কনফিগার বিকল্প সক্ষম করা আছে) #findআনন্দের সাথে অস্পষ্টতাকে উপেক্ষা করবে এবং কেবল প্রথম ম্যাচিং নির্বাচককে ফিরিয়ে দেবে। এটিও দুর্দান্ত নয়, কারণ এটি আপনার চশমাগুলিকে কম স্পষ্ট করে তোলে, যা আমি কল্পনা করি কারণ আর ডিফল্ট আচরণ নেই। আমি নির্দিষ্ট বিবরণগুলি ছেড়ে দেব কারণ তারা ইতিমধ্যে উপরে আলোচনা করা হয়েছে been

আরও সংস্থানসমূহ:



2

উপরের সমস্ত বিকল্প বিবেচনা করে আপনিও এটি ব্যবহার করে দেখতে পারেন

find("a", text: text, match: :prefer_exact).click

আপনি যদি শসা ব্যবহার করেন তবে আপনি এটি অনুসরণ করতে পারেন

আপনি দৃশ্যের পদক্ষেপগুলি থেকে প্যারামিটার হিসাবে পাঠ্যটি পাস করতে পারেন যা পুনরায় ব্যবহারের জন্য সাধারণ পদক্ষেপ হতে পারে

কিছুটা এইরকম When a user clicks on "text" link

এবং পদক্ষেপ সংজ্ঞা When(/^(?:user) clicks on "([^"]*)" (?:link)$/) do |text|

এইভাবে, আপনি কোডের লাইনগুলি হ্রাস করে একই পদক্ষেপটি পুনরায় ব্যবহার করতে পারেন এবং নতুন শসা পরিস্থিতি লিখতে সহজ হবে


0

শসাতে অস্পষ্ট ত্রুটি এড়াতে।

সমাধান 1

first("#tag1").click

সমাধান 2

Cucumber features/filename.feature --guess
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.