306 lines
8.8 KiB
Ruby
306 lines
8.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module FilteredSearchHelpers
|
|
def filtered_search
|
|
page.find('.filtered-search')
|
|
end
|
|
|
|
# Enables input to be set (similar to copy and paste)
|
|
def input_filtered_search(search_term, submit: true, extra_space: true)
|
|
search = search_term
|
|
if extra_space
|
|
# Add an extra space to engage visual tokens
|
|
search = "#{search_term} "
|
|
end
|
|
|
|
filtered_search.set(search, rapid: false)
|
|
|
|
if submit
|
|
# Wait for the lazy author/assignee tokens that
|
|
# swap out the username with an avatar and name
|
|
wait_for_requests
|
|
filtered_search.send_keys(:enter)
|
|
end
|
|
end
|
|
|
|
# Select a label clicking in the search dropdown instead
|
|
# of entering label names on the input.
|
|
def select_label_on_dropdown(label_title)
|
|
input_filtered_search("label:=", submit: false)
|
|
|
|
within('#js-dropdown-label') do
|
|
wait_for_requests
|
|
|
|
find('li', text: label_title).click
|
|
end
|
|
|
|
filtered_search.send_keys(:enter)
|
|
end
|
|
|
|
def expect_filtered_search_dropdown_results(filter_dropdown, count)
|
|
expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: count)
|
|
end
|
|
|
|
def expect_issues_list_count(open_count, closed_count = 0)
|
|
all_count = open_count + closed_count
|
|
|
|
expect(page).to have_issuable_counts(open: open_count, closed: closed_count, all: all_count)
|
|
|
|
expect(page).to have_selector('.issue', count: open_count)
|
|
end
|
|
|
|
# Enables input to be added character by character
|
|
def input_filtered_search_keys(search_term)
|
|
# Add an extra space to engage visual tokens
|
|
filtered_search.send_keys("#{search_term} ")
|
|
filtered_search.send_keys(:enter)
|
|
end
|
|
|
|
def expect_filtered_search_input(input)
|
|
expect(find('.filtered-search').value).to eq(input)
|
|
end
|
|
|
|
def clear_search_field
|
|
find('.filtered-search-box .clear-search').click
|
|
end
|
|
|
|
def reset_filters
|
|
clear_search_field
|
|
filtered_search.send_keys(:enter)
|
|
end
|
|
|
|
def init_label_search
|
|
filtered_search.set('label:=')
|
|
# This ensures the dropdown is shown
|
|
expect(find('#js-dropdown-label')).not_to have_css('.filter-dropdown-loading')
|
|
end
|
|
|
|
def expect_filtered_search_input_empty
|
|
expect(find('.filtered-search').value).to eq('')
|
|
end
|
|
|
|
# Iterates through each visual token inside
|
|
# .tokens-container to make sure the correct names and values are rendered
|
|
def expect_tokens(tokens)
|
|
page.within '.filtered-search-box .tokens-container' do
|
|
token_elements = page.all(:css, 'li.filtered-search-token')
|
|
|
|
tokens.each_with_index do |token, index|
|
|
el = token_elements[index]
|
|
|
|
expect(el.find('.name')).to have_content(token[:name])
|
|
expect(el.find('.operator')).to have_content(token[:operator]) if token[:operator].present?
|
|
expect(el.find('.value')).to have_content(token[:value]) if token[:value].present?
|
|
|
|
# gl-emoji content is blank when the emoji unicode is not supported
|
|
if token[:emoji_name].present?
|
|
selector = %(gl-emoji[data-name="#{token[:emoji_name]}"])
|
|
expect(el.find('.value')).to have_css(selector)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# Same as `expect_tokens` but works with GlFilteredSearch
|
|
def expect_vue_tokens(tokens)
|
|
page.within '.gl-search-box-by-click .gl-filtered-search-scrollable' do
|
|
token_elements = page.all(:css, '.gl-filtered-search-token')
|
|
|
|
tokens.each_with_index do |token, index|
|
|
el = token_elements[index]
|
|
|
|
expect(el.find('.gl-filtered-search-token-type')).to have_content(token[:name])
|
|
expect(el.find('.gl-filtered-search-token-operator')).to have_content(token[:operator]) if token[:operator].present?
|
|
expect(el.find('.gl-filtered-search-token-data')).to have_content(token[:value]) if token[:value].present?
|
|
|
|
# gl-emoji content is blank when the emoji unicode is not supported
|
|
if token[:emoji_name].present?
|
|
selector = %(gl-emoji[data-name="#{token[:emoji_name]}"])
|
|
expect(el.find('.gl-filtered-search-token-data-content')).to have_css(selector)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_token(token_name, token_value = nil, symbol = nil, token_operator = '=')
|
|
{ name: token_name, operator: token_operator, value: "#{symbol}#{token_value}" }
|
|
end
|
|
|
|
def author_token(author_name = nil)
|
|
create_token('Author', author_name)
|
|
end
|
|
|
|
def assignee_token(assignee_name = nil)
|
|
create_token('Assignee', assignee_name)
|
|
end
|
|
|
|
def reviewer_token(reviewer_name = nil)
|
|
create_token('Reviewer', reviewer_name)
|
|
end
|
|
|
|
def milestone_token(milestone_name = nil, has_symbol = true, operator = '=')
|
|
symbol = has_symbol ? '%' : nil
|
|
create_token('Milestone', milestone_name, symbol, operator)
|
|
end
|
|
|
|
def release_token(release_tag = nil)
|
|
create_token('Release', release_tag)
|
|
end
|
|
|
|
def label_token(label_name = nil, has_symbol = true)
|
|
symbol = has_symbol ? '~' : nil
|
|
create_token('Label', label_name, symbol)
|
|
end
|
|
|
|
def reaction_token(reaction_name = nil, is_emoji = true)
|
|
if is_emoji
|
|
{ name: 'My-Reaction', emoji_name: reaction_name }
|
|
else
|
|
create_token('My-Reaction', reaction_name)
|
|
end
|
|
end
|
|
|
|
def default_placeholder
|
|
'Search or filter results...'
|
|
end
|
|
|
|
def get_filtered_search_placeholder
|
|
find('.filtered-search')['placeholder']
|
|
end
|
|
|
|
def remove_recent_searches
|
|
execute_script('window.localStorage.clear();')
|
|
end
|
|
|
|
def set_recent_searches(key, input)
|
|
execute_script("window.localStorage.setItem('#{key}', '#{input}');")
|
|
end
|
|
|
|
def wait_for_filtered_search(text)
|
|
Timeout.timeout(Capybara.default_max_wait_time) do
|
|
loop until find('.filtered-search').value.strip == text
|
|
end
|
|
end
|
|
|
|
def close_dropdown_menu_if_visible
|
|
find('.dropdown-menu-toggle', visible: :all).tap do |toggle|
|
|
toggle.click if toggle.visible?
|
|
end
|
|
end
|
|
|
|
##
|
|
# For use with gl-filtered-search
|
|
def select_tokens(*args, submit: false)
|
|
within '[data-testid="filtered-search-input"]' do
|
|
find_field('Search').click
|
|
|
|
args.each do |token|
|
|
# Move mouse away to prevent invoking tooltips on usernames, which blocks the search input
|
|
find_button('Search').hover
|
|
|
|
if token == '='
|
|
click_on '= is'
|
|
else
|
|
click_on token
|
|
end
|
|
|
|
wait_for_requests
|
|
end
|
|
end
|
|
|
|
if submit
|
|
send_keys :enter
|
|
end
|
|
end
|
|
|
|
def get_suggestion_count
|
|
all('.gl-filtered-search-suggestion').size
|
|
end
|
|
|
|
def submit_search_term(value)
|
|
click_filtered_search_bar
|
|
send_keys(value, :enter)
|
|
end
|
|
|
|
def click_filtered_search_bar
|
|
find('.gl-filtered-search-last-item').click
|
|
end
|
|
|
|
def click_token_segment(value)
|
|
find('.gl-filtered-search-token-segment', text: value).click
|
|
end
|
|
|
|
def expect_visible_suggestions_list
|
|
expect(page).to have_css('.gl-filtered-search-suggestion-list')
|
|
end
|
|
|
|
def expect_hidden_suggestions_list
|
|
expect(page).not_to have_css('.gl-filtered-search-suggestion-list')
|
|
end
|
|
|
|
def expect_suggestion(value)
|
|
expect(page).to have_css('.gl-filtered-search-suggestion', text: value)
|
|
end
|
|
|
|
def expect_no_suggestion(value)
|
|
expect(page).not_to have_css('.gl-filtered-search-suggestion', text: value)
|
|
end
|
|
|
|
def expect_suggestion_count(count)
|
|
expect(page).to have_css('.gl-filtered-search-suggestion', count: count)
|
|
end
|
|
|
|
def expect_assignee_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Assignee = #{value}"
|
|
end
|
|
|
|
def expect_unioned_assignee_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Assignee is one of #{value}"
|
|
end
|
|
|
|
def expect_author_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Author = #{value}"
|
|
end
|
|
|
|
def expect_label_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Label = ~#{value}"
|
|
end
|
|
|
|
def expect_negated_label_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Label != ~#{value}"
|
|
end
|
|
|
|
def expect_milestone_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Milestone = %#{value}"
|
|
end
|
|
|
|
def expect_negated_milestone_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Milestone != %#{value}"
|
|
end
|
|
|
|
def expect_epic_token(value)
|
|
expect(page).to have_css '.gl-filtered-search-token', text: "Epic = #{value}"
|
|
end
|
|
|
|
def expect_search_term(value)
|
|
value.split(' ').each do |term|
|
|
expect(page).to have_css '.gl-filtered-search-term', text: term
|
|
end
|
|
end
|
|
|
|
def expect_empty_search_term
|
|
expect(page).to have_css '.gl-filtered-search-term', text: ''
|
|
end
|
|
|
|
def expect_token_segment(value)
|
|
expect(page).to have_css '.gl-filtered-search-token-segment', text: value
|
|
end
|
|
|
|
def expect_recent_searches_history_item(value)
|
|
expect(page).to have_css '.gl-search-box-by-click-history-item', text: value
|
|
end
|
|
|
|
def expect_recent_searches_history_item_count(count)
|
|
expect(page).to have_css '.gl-search-box-by-click-history-item', count: count
|
|
end
|
|
end
|