Commit 796ce2de authored by Mark Lapierre's avatar Mark Lapierre Committed by Dan Davison

Update all_elements to require constraints

This is more reliable because it imposes certainty on when
Caoybara should stop looking for elements
parent 1fcfac98
...@@ -29,7 +29,7 @@ module QA ...@@ -29,7 +29,7 @@ module QA
end end
def click_first_epic(page = nil) def click_first_epic(page = nil)
all_elements(:epic_title_text).first.click all_elements(:epic_title_text, minimum: 1).first.click
page.validate_elements_present! if page page.validate_elements_present! if page
end end
......
...@@ -106,7 +106,7 @@ module QA ...@@ -106,7 +106,7 @@ module QA
def approvers def approvers
within_element :approver_list do within_element :approver_list do
all_elements(:approver).map { |item| item.find('img')['title'] } all_elements(:approver, minimum: 1).map { |item| item.find('img')['title'] }
end end
end end
......
...@@ -89,6 +89,10 @@ module QA ...@@ -89,6 +89,10 @@ module QA
end end
def all_elements(name, **kwargs) def all_elements(name, **kwargs)
if kwargs.keys.none? { |key| [:minimum, :maximum, :count, :between].include?(key) }
raise ArgumentError, "Please use :minimum, :maximum, :count, or :between so that all is more reliable"
end
wait_for_requests wait_for_requests
all(element_selector_css(name), **kwargs) all(element_selector_css(name), **kwargs)
......
...@@ -45,17 +45,17 @@ module QA ...@@ -45,17 +45,17 @@ module QA
click_element :comment_button click_element :comment_button
end end
def toggle_comments def toggle_comments(position)
all_elements(:toggle_comments_button).last.click all_elements(:toggle_comments_button, minimum: position)[position - 1].click
end end
def type_reply_to_discussion(reply_text) def type_reply_to_discussion(position, reply_text)
all_elements(:discussion_reply_tab).last.click all_elements(:discussion_reply_tab, minimum: position)[position - 1].click
fill_element :reply_input, reply_text fill_element :reply_input, reply_text
end end
def reply_to_discussion(reply_text) def reply_to_discussion(position, reply_text)
type_reply_to_discussion(reply_text) type_reply_to_discussion(position, reply_text)
click_element :reply_comment_button click_element :reply_comment_button
end end
......
...@@ -23,7 +23,7 @@ module QA ...@@ -23,7 +23,7 @@ module QA
def has_detailed_metrics? def has_detailed_metrics?
retry_until(sleep_interval: 1) do retry_until(sleep_interval: 1) do
all_elements(:detailed_metric_content).all? do |metric| all_elements(:detailed_metric_content, count: count).all? do |metric|
metric.has_text?(%r{\d+}) metric.has_text?(%r{\d+})
end end
end end
......
...@@ -76,7 +76,7 @@ module QA ...@@ -76,7 +76,7 @@ module QA
wait(interval: 5) do wait(interval: 5) do
has_text?("No newline at end of file") has_text?("No newline at end of file")
end end
all_elements(:new_diff_line).first.hover all_elements(:new_diff_line, minimum: 1).first.hover
click_element(:diff_comment) click_element(:diff_comment)
fill_element(:reply_input, text) fill_element(:reply_input, text)
end end
......
...@@ -21,10 +21,6 @@ module QA ...@@ -21,10 +21,6 @@ module QA
element :closed_issues_link element :closed_issues_link
end end
def assignee_link_count
all_elements(:assignee_link).count
end
def avatar_counter def avatar_counter
find_element(:avatar_counter) find_element(:avatar_counter)
end end
...@@ -37,6 +33,10 @@ module QA ...@@ -37,6 +33,10 @@ module QA
click_element :closed_issues_link click_element :closed_issues_link
end end
def has_assignee_link_count?(count)
all_elements(:assignee_link, count: count)
end
def has_issue?(issue) def has_issue?(issue)
has_element? :issue, issue_title: issue.to_s has_element? :issue, issue_title: issue.to_s
end end
......
...@@ -56,12 +56,6 @@ module QA ...@@ -56,12 +56,6 @@ module QA
element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern
end end
def avatar_image_count
wait_assignees_block_finish_loading do
all_elements(:avatar_image).count
end
end
def click_milestone_link def click_milestone_link
click_element(:milestone_link) click_element(:milestone_link)
end end
...@@ -88,6 +82,12 @@ module QA ...@@ -88,6 +82,12 @@ module QA
click_element :comment_button click_element :comment_button
end end
def has_avatar_image_count?(count)
wait_assignees_block_finish_loading do
all_elements(:avatar_image, count: count)
end
end
def has_comment?(comment_text) def has_comment?(comment_text)
wait(reload: false) do wait(reload: false) do
has_element?(:noteable_note_item, text: comment_text) has_element?(:noteable_note_item, text: comment_text)
......
...@@ -20,13 +20,13 @@ module QA ...@@ -20,13 +20,13 @@ module QA
end end
def fill_variable(key, value, masked) def fill_variable(key, value, masked)
keys = all_elements(:ci_variable_input_key) keys = all_elements(:ci_variable_input_key, minimum: 1)
index = keys.size - 1 index = keys.size - 1
# After we fill the key, JS would generate another field so # After we fill the key, JS would generate another field so
# we need to use the same index to find the corresponding one. # we need to use the same index to find the corresponding one.
keys[index].set(key) keys[index].set(key)
node = all_elements(:ci_variable_input_value)[index] node = all_elements(:ci_variable_input_value, count: keys.size + 1)[index]
# Simply run `node.set(value)` is too slow for long text here, # Simply run `node.set(value)` is too slow for long text here,
# so we need to run JavaScript directly to set the value. # so we need to run JavaScript directly to set the value.
...@@ -34,7 +34,7 @@ module QA ...@@ -34,7 +34,7 @@ module QA
# https://github.com/teamcapybara/capybara/blob/679548cea10773d45e32808f4d964377cfe5e892/lib/capybara/selenium/node.rb#L217 # https://github.com/teamcapybara/capybara/blob/679548cea10773d45e32808f4d964377cfe5e892/lib/capybara/selenium/node.rb#L217
execute_script("arguments[0].value = #{value.to_json}", node) execute_script("arguments[0].value = #{value.to_json}", node)
masked_node = all_elements(:variable_masked)[index] masked_node = all_elements(:variable_masked, count: keys.size + 1)[index]
toggle_masked(masked_node, masked) toggle_masked(masked_node, masked)
end end
......
...@@ -118,7 +118,7 @@ module QA ...@@ -118,7 +118,7 @@ module QA
def find_repository_row_index(target_url) def find_repository_row_index(target_url)
wait(max: 5, reload: false) do wait(max: 5, reload: false) do
all_elements(:mirror_repository_url_cell).index do |url| all_elements(:mirror_repository_url_cell, minimum: 1).index do |url|
# The url might be a sanitized url but the target_url won't be so # The url might be a sanitized url but the target_url won't be so
# we compare just the paths instead of the full url # we compare just the paths instead of the full url
URI.parse(url.text).path == target_url.path URI.parse(url.text).path == target_url.path
......
...@@ -17,7 +17,7 @@ module QA ...@@ -17,7 +17,7 @@ module QA
Page::Project::Issue::Show.perform do |show| Page::Project::Issue::Show.perform do |show|
show.select_all_activities_filter show.select_all_activities_filter
show.start_discussion('My first discussion') show.start_discussion('My first discussion')
show.reply_to_discussion(my_first_reply) show.reply_to_discussion(1, my_first_reply)
end end
end end
......
...@@ -25,7 +25,7 @@ module QA ...@@ -25,7 +25,7 @@ module QA
Page::Layout::PerformanceBar.perform do |bar_component| Page::Layout::PerformanceBar.perform do |bar_component|
expect(bar_component).to have_performance_bar expect(bar_component).to have_performance_bar
expect(bar_component).to have_detailed_metrics expect(bar_component).to have_detailed_metrics(4)
expect(bar_component).to have_request_for('realtime_changes') # Always requested on issue pages expect(bar_component).to have_request_for('realtime_changes') # Always requested on issue pages
end end
end end
......
...@@ -38,7 +38,7 @@ module QA ...@@ -38,7 +38,7 @@ module QA
Page::Project::Menu.perform(&:click_issues) Page::Project::Menu.perform(&:click_issues)
Page::Project::Issue::Index.perform do |index| Page::Project::Issue::Index.perform do |index|
expect(index.assignee_link_count).to be 4 expect(index).to have_assignee_link_count(4)
end end
end end
end end
......
...@@ -46,7 +46,7 @@ module QA ...@@ -46,7 +46,7 @@ module QA
Page::Project::Menu.perform(&:click_issues) Page::Project::Menu.perform(&:click_issues)
Page::Project::Issue::Index.perform do |index| Page::Project::Issue::Index.perform do |index|
expect(index.assignee_link_count).to be 3 expect(index).to have_assignee_link_count(3)
expect(index.avatar_counter).to be_visible expect(index.avatar_counter).to be_visible
expect(index.avatar_counter).to have_content('+3') expect(index.avatar_counter).to have_content('+3')
end end
...@@ -56,13 +56,13 @@ module QA ...@@ -56,13 +56,13 @@ module QA
@issue.visit! @issue.visit!
Page::Project::Issue::Show.perform do |show| Page::Project::Issue::Show.perform do |show|
expect(show.avatar_image_count).to be 5 expect(show).to have_avatar_image_count(5)
expect(show.more_assignees_link).to be_visible expect(show.more_assignees_link).to be_visible
expect(show.more_assignees_link).to have_content('+ 1 more') expect(show.more_assignees_link).to have_content('+ 1 more')
show.toggle_more_assignees_link show.toggle_more_assignees_link
expect(show.avatar_image_count).to be 6 expect(show).to have_avatar_image_count(6)
expect(show.more_assignees_link).to have_content('- show less') expect(show.more_assignees_link).to have_content('- show less')
end end
end end
......
...@@ -28,7 +28,7 @@ module QA ...@@ -28,7 +28,7 @@ module QA
# You can't start a review immediately, so we have to add a # You can't start a review immediately, so we have to add a
# comment (or start a thread) first # comment (or start a thread) first
show.start_discussion("I'm starting a new discussion") show.start_discussion("I'm starting a new discussion")
show.type_reply_to_discussion("Could you please check this?") show.type_reply_to_discussion(1, "Could you please check this?")
show.start_review show.start_review
show.submit_pending_reviews show.submit_pending_reviews
......
...@@ -73,6 +73,7 @@ module QA ...@@ -73,6 +73,7 @@ module QA
show.edit! show.edit!
approvers = show.approvers approvers = show.approvers
expect(approvers.size).to eq(1)
expect(approvers).to include(approver.name) expect(approvers).to include(approver.name)
expect(approvers).not_to include(non_approver.name) expect(approvers).not_to include(non_approver.name)
end end
......
...@@ -91,4 +91,20 @@ describe QA::Page::Base do ...@@ -91,4 +91,20 @@ describe QA::Page::Base do
end end
end end
end end
describe '#all_elements' do
before do
allow(subject).to receive(:all)
end
it 'raises an error if count or minimum are not specified' do
expect { subject.all_elements(:foo) }.to raise_error ArgumentError
end
it 'does not raise an error if :minimum, :maximum, :count, or :between is specified' do
[:minimum, :maximum, :count, :between].each do |param|
expect { subject.all_elements(:foo, param => 1) }.not_to raise_error
end
end
end
end end
...@@ -145,18 +145,18 @@ describe QA::Support::Page::Logging do ...@@ -145,18 +145,18 @@ describe QA::Support::Page::Logging do
it 'logs the number of elements found' do it 'logs the number of elements found' do
allow(page).to receive(:all).and_return([1, 2]) allow(page).to receive(:all).and_return([1, 2])
expect { subject.all_elements(:element) } expect { subject.all_elements(:element, count: 2) }
.to output(/finding all :element/).to_stdout_from_any_process .to output(/finding all :element/).to_stdout_from_any_process
expect { subject.all_elements(:element) } expect { subject.all_elements(:element, count: 2) }
.to output(/found 2 :element/).to_stdout_from_any_process .to output(/found 2 :element/).to_stdout_from_any_process
end end
it 'logs 0 if no elements are found' do it 'logs 0 if no elements are found' do
allow(page).to receive(:all).and_return([]) allow(page).to receive(:all).and_return([])
expect { subject.all_elements(:element) } expect { subject.all_elements(:element, count: 1) }
.to output(/finding all :element/).to_stdout_from_any_process .to output(/finding all :element/).to_stdout_from_any_process
expect { subject.all_elements(:element) } expect { subject.all_elements(:element, count: 1) }
.not_to output(/found 0 :elements/).to_stdout_from_any_process .not_to output(/found 0 :elements/).to_stdout_from_any_process
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment