Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClement Ho <ClemMakesApps@gmail.com>2017-01-31 01:53:18 +0300
committerClement Ho <ClemMakesApps@gmail.com>2017-03-08 08:10:32 +0300
commitf44fb5cfd0cc4baada4d88f9724c74fc44326637 (patch)
treee2ff8e5e9b0d14b87aad353abffdc9b7979d6a29 /spec/features/issues/filtered_search
parentb5cb1115f4e3357118465ea4becf031b4ea598a6 (diff)
Add filtered search visual tokens
Diffstat (limited to 'spec/features/issues/filtered_search')
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb12
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb7
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb63
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb31
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb28
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb367
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb306
8 files changed, 624 insertions, 194 deletions
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index ede6aa0c201..4dcc56a97d1 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -1,6 +1,9 @@
require 'rails_helper'
describe 'Dropdown assignee', :feature, :js do
+ include FilteredSearchHelpers
+ include WaitForAjax
+
let!(:project) { create(:empty_project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
let!(:user_john) { create(:user, name: 'John', username: 'th0mas') }
@@ -133,7 +136,8 @@ describe 'Dropdown assignee', :feature, :js do
click_assignee(user_jacob.name)
expect(page).to have_css(js_dropdown_assignee, visible: false)
- expect(filtered_search.value).to eq("assignee:@#{user_jacob.username} ")
+ expect_tokens([{ name: 'assignee', value: "@#{user_jacob.username}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the assignee username when the assignee has been filtered' do
@@ -141,14 +145,16 @@ describe 'Dropdown assignee', :feature, :js do
click_assignee(user.name)
expect(page).to have_css(js_dropdown_assignee, visible: false)
- expect(filtered_search.value).to eq("assignee:@#{user.username} ")
+ expect_tokens([{ name: 'assignee', value: "@#{user.username}" }])
+ expect_filtered_search_input_empty
end
it 'selects `no assignee`' do
find('#js-dropdown-assignee .filter-dropdown-item', text: 'No Assignee').click
expect(page).to have_css(js_dropdown_assignee, visible: false)
- expect(filtered_search.value).to eq("assignee:none ")
+ expect_tokens([{ name: 'assignee', value: 'none' }])
+ expect_filtered_search_input_empty
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index 59e302f0e2d..19a00618b12 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -1,6 +1,7 @@
require 'rails_helper'
describe 'Dropdown author', js: true, feature: true do
+ include FilteredSearchHelpers
include WaitForAjax
let!(:project) { create(:empty_project) }
@@ -121,14 +122,16 @@ describe 'Dropdown author', js: true, feature: true do
click_author(user_jacob.name)
expect(page).to have_css(js_dropdown_author, visible: false)
- expect(filtered_search.value).to eq("author:@#{user_jacob.username} ")
+ expect_tokens([{ name: 'author', value: "@#{user_jacob.username}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the author username when the author has been filtered' do
click_author(user.name)
expect(page).to have_css(js_dropdown_author, visible: false)
- expect(filtered_search.value).to eq("author:@#{user.username} ")
+ expect_tokens([{ name: 'author', value: "@#{user.username}" }])
+ expect_filtered_search_input_empty
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index 04dd54ab459..01b657bcada 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -1,6 +1,7 @@
require 'rails_helper'
describe 'Dropdown hint', js: true, feature: true do
+ include FilteredSearchHelpers
include WaitForAjax
let!(:project) { create(:empty_project) }
@@ -66,7 +67,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-author', visible: true)
- expect(filtered_search.value).to eq('author:')
+ expect_tokens([{ name: 'author' }])
+ expect_filtered_search_input_empty
end
it 'opens the assignee dropdown when you click on assignee' do
@@ -74,7 +76,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-assignee', visible: true)
- expect(filtered_search.value).to eq('assignee:')
+ expect_tokens([{ name: 'assignee' }])
+ expect_filtered_search_input_empty
end
it 'opens the milestone dropdown when you click on milestone' do
@@ -82,7 +85,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-milestone', visible: true)
- expect(filtered_search.value).to eq('milestone:')
+ expect_tokens([{ name: 'milestone' }])
+ expect_filtered_search_input_empty
end
it 'opens the label dropdown when you click on label' do
@@ -90,7 +94,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-label', visible: true)
- expect(filtered_search.value).to eq('label:')
+ expect_tokens([{ name: 'label' }])
+ expect_filtered_search_input_empty
end
end
@@ -101,7 +106,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-author', visible: true)
- expect(filtered_search.value).to eq('author:')
+ expect_tokens([{ name: 'author' }])
+ expect_filtered_search_input_empty
end
it 'opens the assignee dropdown when you click on assignee' do
@@ -110,7 +116,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-assignee', visible: true)
- expect(filtered_search.value).to eq('assignee:')
+ expect_tokens([{ name: 'assignee' }])
+ expect_filtered_search_input_empty
end
it 'opens the milestone dropdown when you click on milestone' do
@@ -119,7 +126,8 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-milestone', visible: true)
- expect(filtered_search.value).to eq('milestone:')
+ expect_tokens([{ name: 'milestone' }])
+ expect_filtered_search_input_empty
end
it 'opens the label dropdown when you click on label' do
@@ -128,7 +136,46 @@ describe 'Dropdown hint', js: true, feature: true do
expect(page).to have_css(js_dropdown_hint, visible: false)
expect(page).to have_css('#js-dropdown-label', visible: true)
- expect(filtered_search.value).to eq('label:')
+ expect_tokens([{ name: 'label' }])
+ expect_filtered_search_input_empty
+ end
+ end
+
+ describe 'reselecting from dropdown' do
+ it 'reuses existing author text' do
+ filtered_search.send_keys('author:')
+ filtered_search.send_keys(:backspace)
+ click_hint('author')
+
+ expect_tokens([{ name: 'author' }])
+ expect_filtered_search_input_empty
+ end
+
+ it 'reuses existing assignee text' do
+ filtered_search.send_keys('assignee:')
+ filtered_search.send_keys(:backspace)
+ click_hint('assignee')
+
+ expect_tokens([{ name: 'assignee' }])
+ expect_filtered_search_input_empty
+ end
+
+ it 'reuses existing milestone text' do
+ filtered_search.send_keys('milestone:')
+ filtered_search.send_keys(:backspace)
+ click_hint('milestone')
+
+ expect_tokens([{ name: 'milestone' }])
+ expect_filtered_search_input_empty
+ end
+
+ it 'reuses existing label text' do
+ filtered_search.send_keys('label:')
+ filtered_search.send_keys(:backspace)
+ click_hint('label')
+
+ expect_tokens([{ name: 'label' }])
+ expect_filtered_search_input_empty
end
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index ab3b868fd3a..b192064b693 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -51,7 +51,8 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search.native.send_keys(:down, :down, :enter)
- expect(filtered_search.value).to eq("label:~#{bug_label.title} ")
+ expect_tokens([{ name: 'label', value: "~#{bug_label.title}" }])
+ expect_filtered_search_input_empty
end
end
@@ -92,7 +93,7 @@ describe 'Dropdown label', js: true, feature: true do
end
it 'filters by case-insensitive name with or without symbol' do
- search_for_label('b')
+ filtered_search.send_keys('b')
expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible
@@ -101,7 +102,7 @@ describe 'Dropdown label', js: true, feature: true do
clear_search_field
init_label_search
- search_for_label('~bu')
+ filtered_search.send_keys('~bu')
expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible
@@ -180,7 +181,8 @@ describe 'Dropdown label', js: true, feature: true do
click_label(bug_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~#{bug_label.title} ")
+ expect_tokens([{ name: 'label', value: "~#{bug_label.title}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the label name when the label is partially filled' do
@@ -188,49 +190,56 @@ describe 'Dropdown label', js: true, feature: true do
click_label(bug_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~#{bug_label.title} ")
+ expect_tokens([{ name: 'label', value: "~#{bug_label.title}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the label name that contains multiple words' do
click_label(two_words_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~\"#{two_words_label.title}\" ")
+ expect_tokens([{ name: 'label', value: "\"#{two_words_label.title}\"" }])
+ expect_filtered_search_input_empty
end
it 'fills in the label name that contains multiple words and is very long' do
click_label(long_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~\"#{long_label.title}\" ")
+ expect_tokens([{ name: 'label', value: "\"#{long_label.title}\"" }])
+ expect_filtered_search_input_empty
end
it 'fills in the label name that contains double quotes' do
click_label(wont_fix_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~'#{wont_fix_label.title}' ")
+ expect_tokens([{ name: 'label', value: "~'#{wont_fix_label.title}'" }])
+ expect_filtered_search_input_empty
end
it 'fills in the label name with the correct capitalization' do
click_label(uppercase_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~#{uppercase_label.title} ")
+ expect_tokens([{ name: 'label', value: "~#{uppercase_label.title}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the label name with special characters' do
click_label(special_label.title)
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:~#{special_label.title} ")
+ expect_tokens([{ name: 'label', value: "~#{special_label.title}" }])
+ expect_filtered_search_input_empty
end
it 'selects `no label`' do
find("#{js_dropdown_label} .filter-dropdown-item", text: 'No Label').click
expect(page).not_to have_css(js_dropdown_label)
- expect(filtered_search.value).to eq("label:none ")
+ expect_tokens([{ name: 'label', value: 'none' }])
+ expect_filtered_search_input_empty
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index 0ce16715b86..0324fcad0a0 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -1,6 +1,7 @@
require 'rails_helper'
describe 'Dropdown milestone', js: true, feature: true do
+ include FilteredSearchHelpers
include WaitForAjax
let!(:project) { create(:empty_project) }
@@ -127,7 +128,8 @@ describe 'Dropdown milestone', js: true, feature: true do
click_milestone(milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%#{milestone.title} ")
+ expect_tokens([{ name: 'milestone', value: "%#{milestone.title}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the milestone name when the milestone is partially filled' do
@@ -135,56 +137,64 @@ describe 'Dropdown milestone', js: true, feature: true do
click_milestone(milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%#{milestone.title} ")
+ expect_tokens([{ name: 'milestone', value: "%#{milestone.title}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the milestone name that contains multiple words' do
click_milestone(two_words_milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%\"#{two_words_milestone.title}\" ")
+ expect_tokens([{ name: 'milestone', value: "%\"#{two_words_milestone.title}\"" }])
+ expect_filtered_search_input_empty
end
it 'fills in the milestone name that contains multiple words and is very long' do
click_milestone(long_milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%\"#{long_milestone.title}\" ")
+ expect_tokens([{ name: 'milestone', value: "%\"#{long_milestone.title}\"" }])
+ expect_filtered_search_input_empty
end
it 'fills in the milestone name that contains double quotes' do
click_milestone(wont_fix_milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%'#{wont_fix_milestone.title}' ")
+ expect_tokens([{ name: 'milestone', value: "%'#{wont_fix_milestone.title}'" }])
+ expect_filtered_search_input_empty
end
it 'fills in the milestone name with the correct capitalization' do
click_milestone(uppercase_milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%#{uppercase_milestone.title} ")
+ expect_tokens([{ name: 'milestone', value: "%#{uppercase_milestone.title}" }])
+ expect_filtered_search_input_empty
end
it 'fills in the milestone name with special characters' do
click_milestone(special_milestone.title)
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:%#{special_milestone.title} ")
+ expect_tokens([{ name: 'milestone', value: "%#{special_milestone.title}" }])
+ expect_filtered_search_input_empty
end
it 'selects `no milestone`' do
click_static_milestone('No Milestone')
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:none ")
+ expect_tokens([{ name: 'milestone', value: 'none' }])
+ expect_filtered_search_input_empty
end
it 'selects `upcoming milestone`' do
click_static_milestone('Upcoming')
expect(page).to have_css(js_dropdown_milestone, visible: false)
- expect(filtered_search.value).to eq("milestone:upcoming ")
+ expect_tokens([{ name: 'milestone', value: 'upcoming' }])
+ expect_filtered_search_input_empty
end
end
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 0420e64d42c..35bd37933bc 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -1,4 +1,4 @@
-require 'rails_helper'
+require 'spec_helper'
describe 'Filter issues', js: true, feature: true do
include FilteredSearchHelpers
@@ -97,7 +97,9 @@ describe 'Filter issues', js: true, feature: true do
it 'filters issues by searched author' do
input_filtered_search("author:@#{user.username}")
+ expect_tokens([{ name: 'author', value: user.username }])
expect_issues_list_count(5)
+ expect_filtered_search_input_empty
end
it 'filters issues by invalid author' do
@@ -110,36 +112,50 @@ describe 'Filter issues', js: true, feature: true do
end
context 'author with other filters' do
+ search_term = 'issue'
+
it 'filters issues by searched author and text' do
- search = "author:@#{user.username} issue"
- input_filtered_search(search)
+ input_filtered_search("author:@#{user.username} #{search_term}")
+ expect_tokens([{ name: 'author', value: user.username }])
expect_issues_list_count(3)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched author, assignee and text' do
- search = "author:@#{user.username} assignee:@#{user.username} issue"
- input_filtered_search(search)
+ input_filtered_search("author:@#{user.username} assignee:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username }
+ ])
expect_issues_list_count(3)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched author, assignee, label, and text' do
- search = "author:@#{user.username} assignee:@#{user.username} label:~#{caps_sensitive_label.title} issue"
- input_filtered_search(search)
+ input_filtered_search("author:@#{user.username} assignee:@#{user.username} label:~#{caps_sensitive_label.title} #{search_term}")
+ expect_tokens([
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username },
+ { name: 'label', value: caps_sensitive_label.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched author, assignee, label, milestone and text' do
- search = "author:@#{user.username} assignee:@#{user.username} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} issue"
- input_filtered_search(search)
+ input_filtered_search("author:@#{user.username} assignee:@#{user.username} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} #{search_term}")
+ expect_tokens([
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username },
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'milestone', value: milestone.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
end
@@ -151,19 +167,19 @@ describe 'Filter issues', js: true, feature: true do
describe 'filter issues by assignee' do
context 'only assignee' do
it 'filters issues by searched assignee' do
- search = "assignee:@#{user.username}"
- input_filtered_search(search)
+ input_filtered_search("assignee:@#{user.username}")
+ expect_tokens([{ name: 'assignee', value: user.username }])
expect_issues_list_count(5)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'filters issues by no assignee' do
- search = "assignee:none"
- input_filtered_search(search)
+ input_filtered_search('assignee:none')
+ expect_tokens([{ name: 'assignee', value: 'none' }])
expect_issues_list_count(8, 1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'filters issues by invalid assignee' do
@@ -176,36 +192,50 @@ describe 'Filter issues', js: true, feature: true do
end
context 'assignee with other filters' do
+ let(:search_term) { 'searchTerm' }
+
it 'filters issues by searched assignee and text' do
- search = "assignee:@#{user.username} searchTerm"
- input_filtered_search(search)
+ input_filtered_search("assignee:@#{user.username} #{search_term}")
+ expect_tokens([{ name: 'assignee', value: user.username }])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched assignee, author and text' do
- search = "assignee:@#{user.username} author:@#{user.username} searchTerm"
- input_filtered_search(search)
+ input_filtered_search("assignee:@#{user.username} author:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'assignee', value: user.username },
+ { name: 'author', value: user.username }
+ ])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched assignee, author, label, text' do
- search = "assignee:@#{user.username} author:@#{user.username} label:~#{caps_sensitive_label.title} searchTerm"
- input_filtered_search(search)
+ input_filtered_search("assignee:@#{user.username} author:@#{user.username} label:~#{caps_sensitive_label.title} #{search_term}")
+ expect_tokens([
+ { name: 'assignee', value: user.username },
+ { name: 'author', value: user.username },
+ { name: 'label', value: caps_sensitive_label.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched assignee, author, label, milestone and text' do
- search = "assignee:@#{user.username} author:@#{user.username} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} searchTerm"
- input_filtered_search(search)
+ input_filtered_search("assignee:@#{user.username} author:@#{user.username} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} #{search_term}")
+ expect_tokens([
+ { name: 'assignee', value: user.username },
+ { name: 'author', value: user.username },
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'milestone', value: milestone.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
end
@@ -217,21 +247,23 @@ describe 'Filter issues', js: true, feature: true do
end
describe 'filter issues by label' do
+ let(:search_term) { 'bug' }
+
context 'only label' do
it 'filters issues by searched label' do
- search = "label:~#{bug_label.title}"
- input_filtered_search(search)
+ input_filtered_search("label:~#{bug_label.title}")
+ expect_tokens([{ name: 'label', value: bug_label.title }])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'filters issues by no label' do
- search = "label:none"
- input_filtered_search(search)
+ input_filtered_search('label:none')
+ expect_tokens([{ name: 'label', value: 'none' }])
expect_issues_list_count(9, 1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'filters issues by invalid label' do
@@ -239,11 +271,14 @@ describe 'Filter issues', js: true, feature: true do
end
it 'filters issues by multiple labels' do
- search = "label:~#{bug_label.title} label:~#{caps_sensitive_label.title}"
- input_filtered_search(search)
+ input_filtered_search("label:~#{bug_label.title} label:~#{caps_sensitive_label.title}")
+ expect_tokens([
+ { name: 'label', value: bug_label.title },
+ { name: 'label', value: caps_sensitive_label.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'filters issues by label containing special characters' do
@@ -251,21 +286,20 @@ describe 'Filter issues', js: true, feature: true do
special_issue = create(:issue, title: "Issue with special character label", project: project)
special_issue.labels << special_label
- search = "label:~#{special_label.title}"
- input_filtered_search(search)
-
+ input_filtered_search("label:~#{special_label.title}")
+ expect_tokens([{ name: 'label', value: special_label.title }])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'does not show issues' do
- new_label = create(:label, project: project, title: "new_label")
+ new_label = create(:label, project: project, title: 'new_label')
- search = "label:~#{new_label.title}"
- input_filtered_search(search)
+ input_filtered_search("label:~#{new_label.title}")
+ expect_tokens([{ name: 'label', value: new_label.title }])
expect_no_issues_list()
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
end
@@ -275,29 +309,29 @@ describe 'Filter issues', js: true, feature: true do
special_multiple_issue = create(:issue, title: "Issue with special character multiple words label", project: project)
special_multiple_issue.labels << special_multiple_label
- search = "label:~'#{special_multiple_label.title}'"
- input_filtered_search(search)
+ input_filtered_search("label:~'#{special_multiple_label.title}'")
+ # filtered search defaults quotations to double quotes
+ expect_tokens([{ name: 'label', value: "\"#{special_multiple_label.title}\"" }])
expect_issues_list_count(1)
- # filtered search defaults quotations to double quotes
- expect_filtered_search_input("label:~\"#{special_multiple_label.title}\"")
+ expect_filtered_search_input_empty
end
it 'single quotes' do
- search = "label:~'#{multiple_words_label.title}'"
- input_filtered_search(search)
+ input_filtered_search("label:~'#{multiple_words_label.title}'")
+ expect_tokens([{ name: 'label', value: "\"#{multiple_words_label.title}\"" }])
expect_issues_list_count(1)
- expect_filtered_search_input("label:~\"#{multiple_words_label.title}\"")
+ expect_filtered_search_input_empty
end
it 'double quotes' do
- search = "label:~\"#{multiple_words_label.title}\""
- input_filtered_search(search)
+ input_filtered_search("label:~\"#{multiple_words_label.title}\"")
+ expect_tokens([{ name: 'label', value: "\"#{multiple_words_label.title}\"" }])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'single quotes containing double quotes' do
@@ -305,11 +339,11 @@ describe 'Filter issues', js: true, feature: true do
double_quotes_label_issue = create(:issue, title: "Issue with double quotes label", project: project)
double_quotes_label_issue.labels << double_quotes_label
- search = "label:~'#{double_quotes_label.title}'"
- input_filtered_search(search)
+ input_filtered_search("label:~'#{double_quotes_label.title}'")
+ expect_tokens([{ name: 'label', value: "'#{double_quotes_label.title}'" }])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'double quotes containing single quotes' do
@@ -317,86 +351,115 @@ describe 'Filter issues', js: true, feature: true do
single_quotes_label_issue = create(:issue, title: "Issue with single quotes label", project: project)
single_quotes_label_issue.labels << single_quotes_label
- search = "label:~\"#{single_quotes_label.title}\""
- input_filtered_search(search)
+ input_filtered_search("label:~\"#{single_quotes_label.title}\"")
+ expect_tokens([{ name: 'label', value: "\"#{single_quotes_label.title}\"" }])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
end
context 'label with other filters' do
it 'filters issues by searched label and text' do
- search = "label:~#{caps_sensitive_label.title} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{caps_sensitive_label.title} #{search_term}")
+ expect_tokens([{ name: 'label', value: caps_sensitive_label.title }])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched label, author and text' do
- search = "label:~#{caps_sensitive_label.title} author:@#{user.username} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{caps_sensitive_label.title} author:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'author', value: user.username }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched label, author, assignee and text' do
- search = "label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched label, author, assignee, milestone and text' do
- search = "label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} milestone:%#{milestone.title} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} milestone:%#{milestone.title} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username },
+ { name: 'milestone', value: milestone.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
end
context 'multiple labels with other filters' do
it 'filters issues by searched label, label2, and text' do
- search = "label:~#{bug_label.title} label:~#{caps_sensitive_label.title} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{bug_label.title} label:~#{caps_sensitive_label.title} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: bug_label.title },
+ { name: 'label', value: caps_sensitive_label.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched label, label2, author and text' do
- search = "label:~#{bug_label.title} label:~#{caps_sensitive_label.title} author:@#{user.username} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{bug_label.title} label:~#{caps_sensitive_label.title} author:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: bug_label.title },
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'author', value: user.username }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched label, label2, author, assignee and text' do
- search = "label:~#{bug_label.title} label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{bug_label.title} label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: bug_label.title },
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched label, label2, author, assignee, milestone and text' do
- search = "label:~#{bug_label.title} label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} milestone:%#{milestone.title} bug"
- input_filtered_search(search)
+ input_filtered_search("label:~#{bug_label.title} label:~#{caps_sensitive_label.title} author:@#{user.username} assignee:@#{user.username} milestone:%#{milestone.title} #{search_term}")
+ expect_tokens([
+ { name: 'label', value: bug_label.title },
+ { name: 'label', value: caps_sensitive_label.title },
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username },
+ { name: 'milestone', value: milestone.title }
+ ])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
end
context 'issue label clicked' do
before do
find('.issues-list .issue .issue-info a .label', text: multiple_words_label.title).click
- sleep 1
end
it 'filters' do
@@ -404,7 +467,8 @@ describe 'Filter issues', js: true, feature: true do
end
it 'displays in search bar' do
- expect(find('.filtered-search').value).to eq("label:~\"#{multiple_words_label.title}\"")
+ expect_tokens([{ name: 'label', value: "\"#{multiple_words_label.title}\"" }])
+ expect_filtered_search_input_empty
end
end
@@ -420,19 +484,25 @@ describe 'Filter issues', js: true, feature: true do
it 'filters issues by searched milestone' do
input_filtered_search("milestone:%#{milestone.title}")
+ expect_tokens([{ name: 'milestone', value: milestone.title }])
expect_issues_list_count(5)
+ expect_filtered_search_input_empty
end
it 'filters issues by no milestone' do
input_filtered_search("milestone:none")
+ expect_tokens([{ name: 'milestone', value: 'none' }])
expect_issues_list_count(7, 1)
+ expect_filtered_search_input_empty
end
it 'filters issues by upcoming milestones' do
input_filtered_search("milestone:upcoming")
+ expect_tokens([{ name: 'milestone', value: 'upcoming' }])
expect_issues_list_count(1)
+ expect_filtered_search_input_empty
end
it 'filters issues by invalid milestones' do
@@ -447,55 +517,69 @@ describe 'Filter issues', js: true, feature: true do
special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project)
create(:issue, title: "Issue with special character milestone", project: project, milestone: special_milestone)
- search = "milestone:%#{special_milestone.title}"
- input_filtered_search(search)
+ input_filtered_search("milestone:%#{special_milestone.title}")
+ expect_tokens([{ name: 'milestone', value: special_milestone.title }])
expect_issues_list_count(1)
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
it 'does not show issues' do
new_milestone = create(:milestone, title: "new", project: project)
- search = "milestone:%#{new_milestone.title}"
- input_filtered_search(search)
+ input_filtered_search("milestone:%#{new_milestone.title}")
+ expect_tokens([{ name: 'milestone', value: new_milestone.title }])
expect_no_issues_list()
- expect_filtered_search_input(search)
+ expect_filtered_search_input_empty
end
end
context 'milestone with other filters' do
+ search_term = 'bug'
+
it 'filters issues by searched milestone and text' do
- search = "milestone:%#{milestone.title} bug"
- input_filtered_search(search)
+ input_filtered_search("milestone:%#{milestone.title} #{search_term}")
+ expect_tokens([{ name: 'milestone', value: milestone.title }])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched milestone, author and text' do
- search = "milestone:%#{milestone.title} author:@#{user.username} bug"
- input_filtered_search(search)
+ input_filtered_search("milestone:%#{milestone.title} author:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'milestone', value: milestone.title },
+ { name: 'author', value: user.username }
+ ])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched milestone, author, assignee and text' do
- search = "milestone:%#{milestone.title} author:@#{user.username} assignee:@#{user.username} bug"
- input_filtered_search(search)
+ input_filtered_search("milestone:%#{milestone.title} author:@#{user.username} assignee:@#{user.username} #{search_term}")
+ expect_tokens([
+ { name: 'milestone', value: milestone.title },
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username }
+ ])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
it 'filters issues by searched milestone, author, assignee, label and text' do
- search = "milestone:%#{milestone.title} author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} bug"
- input_filtered_search(search)
-
+ input_filtered_search("milestone:%#{milestone.title} author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} #{search_term}")
+
+ expect_tokens([
+ { name: 'milestone', value: milestone.title },
+ { name: 'author', value: user.username },
+ { name: 'assignee', value: user.username },
+ { name: 'label', value: bug_label.title }
+ ])
expect_issues_list_count(2)
- expect_filtered_search_input(search)
+ expect_filtered_search_input(search_term)
end
end
@@ -506,44 +590,6 @@ describe 'Filter issues', js: true, feature: true do
end
end
- describe 'overwrites selected filter' do
- it 'changes author' do
- input_filtered_search("author:@#{user.username}", submit: false)
-
- select_search_at_index(3)
-
- page.within '#js-dropdown-author' do
- click_button user2.username
- end
-
- expect(filtered_search.value).to eq("author:@#{user2.username} ")
- end
-
- it 'changes label' do
- input_filtered_search("author:@#{user.username} label:~#{bug_label.title}", submit: false)
-
- select_search_at_index(27)
-
- page.within '#js-dropdown-label' do
- click_button label.name
- end
-
- expect(filtered_search.value).to eq("author:@#{user.username} label:~#{label.name} ")
- end
-
- it 'changes label correctly space is in previous label' do
- input_filtered_search("label:~\"#{multiple_words_label.title}\"", submit: false)
-
- select_search_at_index(0)
-
- page.within '#js-dropdown-label' do
- click_button label.name
- end
-
- expect(filtered_search.value).to eq("label:~#{label.name} ")
- end
- end
-
describe 'filter issues by text' do
context 'only text' do
it 'filters issues by searched text' do
@@ -605,80 +651,81 @@ describe 'Filter issues', js: true, feature: true do
context 'searched text with other filters' do
it 'filters issues by searched text and author' do
+ # After searching, all search terms are placed at the end
input_filtered_search("bug author:@#{user.username}")
expect_issues_list_count(2)
- expect_filtered_search_input("author:@#{user.username} bug")
+ expect_filtered_search_input('bug')
end
it 'filters issues by searched text, author and more text' do
input_filtered_search("bug author:@#{user.username} report")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} bug report")
+ expect_filtered_search_input('bug report')
end
it 'filters issues by searched text, author and assignee' do
input_filtered_search("bug author:@#{user.username} assignee:@#{user.username}")
expect_issues_list_count(2)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} bug")
+ expect_filtered_search_input('bug')
end
it 'filters issues by searched text, author, more text and assignee' do
input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username}")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} bug report")
+ expect_filtered_search_input('bug report')
end
it 'filters issues by searched text, author, more text, assignee and even more text' do
input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} bug report with")
+ expect_filtered_search_input('bug report with')
end
it 'filters issues by searched text, author, assignee and label' do
input_filtered_search("bug author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title}")
expect_issues_list_count(2)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} bug")
+ expect_filtered_search_input('bug')
end
it 'filters issues by searched text, author, text, assignee, text, label and text' do
input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with label:~#{bug_label.title} everything")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} bug report with everything")
+ expect_filtered_search_input('bug report with everything')
end
it 'filters issues by searched text, author, assignee, label and milestone' do
input_filtered_search("bug author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} milestone:%#{milestone.title}")
expect_issues_list_count(2)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} milestone:%#{milestone.title} bug")
+ expect_filtered_search_input('bug')
end
it 'filters issues by searched text, author, text, assignee, text, label, text, milestone and text' do
input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with label:~#{bug_label.title} everything milestone:%#{milestone.title} you")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} milestone:%#{milestone.title} bug report with everything you")
+ expect_filtered_search_input('bug report with everything you')
end
it 'filters issues by searched text, author, assignee, multiple labels and milestone' do
input_filtered_search("bug author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title}")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} bug")
+ expect_filtered_search_input('bug')
end
it 'filters issues by searched text, author, text, assignee, text, label1, text, label2, text, milestone and text' do
input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with label:~#{bug_label.title} everything label:~#{caps_sensitive_label.title} you milestone:%#{milestone.title} thought")
expect_issues_list_count(1)
- expect_filtered_search_input("author:@#{user.username} assignee:@#{user.username} label:~#{bug_label.title} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} bug report with everything you thought")
+ expect_filtered_search_input('bug report with everything you thought')
end
end
@@ -717,8 +764,8 @@ describe 'Filter issues', js: true, feature: true do
before do
input_filtered_search('bug')
- # Wait for search results to load
- sleep 2
+ # This ensures that the search is performed
+ expect_issues_list_count(4, 1)
end
it 'open state' do
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 90eb60eb337..59244d65eec 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -1,6 +1,7 @@
require 'rails_helper'
describe 'Search bar', js: true, feature: true do
+ include FilteredSearchHelpers
include WaitForAjax
let!(:project) { create(:empty_project) }
@@ -32,7 +33,8 @@ describe 'Search bar', js: true, feature: true do
it 'selects item' do
filtered_search.native.send_keys(:down, :down, :enter)
- expect(filtered_search.value).to eq('author:')
+ expect_tokens([{ name: 'author' }])
+ expect_filtered_search_input_empty
end
end
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
new file mode 100644
index 00000000000..b62a6d7913d
--- /dev/null
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -0,0 +1,306 @@
+require 'rails_helper'
+
+describe 'Visual tokens', js: true, feature: true do
+ include FilteredSearchHelpers
+
+ let!(:project) { create(:empty_project) }
+ let!(:user) { create(:user, name: 'administrator', username: 'root') }
+ let!(:user_rock) { create(:user, name: 'The Rock', username: 'rock') }
+ let!(:milestone_nine) { create(:milestone, title: '9.0', project: project) }
+ let!(:milestone_ten) { create(:milestone, title: '10.0', project: project) }
+ let!(:label) { create(:label, project: project, title: 'abc') }
+ let!(:cc_label) { create(:label, project: project, title: 'Community Contribution') }
+
+ let(:filtered_search) { find('.filtered-search') }
+ let(:filter_author_dropdown) { find("#js-dropdown-author .filter-dropdown") }
+ let(:filter_assignee_dropdown) { find("#js-dropdown-assignee .filter-dropdown") }
+ let(:filter_milestone_dropdown) { find("#js-dropdown-milestone .filter-dropdown") }
+ let(:filter_label_dropdown) { find("#js-dropdown-label .filter-dropdown") }
+
+ def is_input_focused
+ page.evaluate_script("document.activeElement.classList.contains('filtered-search')")
+ end
+
+ before do
+ project.add_user(user, :master)
+ project.add_user(user_rock, :master)
+ login_as(user)
+ create(:issue, project: project)
+
+ visit namespace_project_issues_path(project.namespace, project)
+ end
+
+ describe 'editing author token' do
+ before do
+ input_filtered_search('author:@root assignee:none', submit: false)
+ first('.tokens-container .filtered-search-token').double_click
+ end
+
+ it 'opens author dropdown' do
+ expect(page).to have_css('#js-dropdown-author', visible: true)
+ end
+
+ it 'makes value editable' do
+ expect_filtered_search_input('@root')
+ end
+
+ it 'filters value' do
+ filtered_search.send_keys(:backspace)
+
+ expect(page).to have_css('#js-dropdown-author .filter-dropdown .filter-dropdown-item', count: 1)
+ end
+
+ it 'ends editing mode when document is clicked' do
+ find('#content-body').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-author', visible: false)
+ end
+
+ it 'ends editing mode when scroll container is clicked' do
+ find('.scroll-container').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-author', visible: false)
+ end
+
+ describe 'selecting different author from dropdown' do
+ before do
+ filter_author_dropdown.find('.filter-dropdown-item .dropdown-light-content', text: "@#{user_rock.username}").click
+ end
+
+ it 'changes value in visual token' do
+ expect(first('.tokens-container .filtered-search-token .value').text).to eq("@#{user_rock.username}")
+ end
+
+ it 'moves input to the right' do
+ expect(is_input_focused).to eq(true)
+ end
+ end
+ end
+
+ describe 'editing assignee token' do
+ before do
+ input_filtered_search('assignee:@root author:none', submit: false)
+ first('.tokens-container .filtered-search-token').double_click
+ end
+
+ it 'opens assignee dropdown' do
+ expect(page).to have_css('#js-dropdown-assignee', visible: true)
+ end
+
+ it 'makes value editable' do
+ expect_filtered_search_input('@root')
+ end
+
+ it 'filters value' do
+ filtered_search.send_keys(:backspace)
+
+ expect(page).to have_css('#js-dropdown-assignee .filter-dropdown .filter-dropdown-item', count: 1)
+ end
+
+ it 'ends editing mode when document is clicked' do
+ find('#content-body').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-assignee', visible: false)
+ end
+
+ it 'ends editing mode when scroll container is clicked' do
+ find('.scroll-container').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-assignee', visible: false)
+ end
+
+ describe 'selecting static option from dropdown' do
+ before do
+ find("#js-dropdown-assignee").find('.filter-dropdown-item', text: 'No Assignee').click
+ end
+
+ it 'changes value in visual token' do
+ expect(first('.tokens-container .filtered-search-token .value').text).to eq('none')
+ end
+
+ it 'moves input to the right' do
+ expect(is_input_focused).to eq(true)
+ end
+ end
+ end
+
+ describe 'editing milestone token' do
+ before do
+ input_filtered_search('milestone:%10.0 author:none', submit: false)
+ first('.tokens-container .filtered-search-token').double_click
+ first('#js-dropdown-milestone .filter-dropdown .filter-dropdown-item')
+ end
+
+ it 'opens milestone dropdown' do
+ expect(filter_milestone_dropdown.find('.filter-dropdown-item', text: milestone_ten.title)).to be_visible
+ expect(filter_milestone_dropdown.find('.filter-dropdown-item', text: milestone_nine.title)).to be_visible
+ expect(page).to have_css('#js-dropdown-milestone', visible: true)
+ end
+
+ it 'selects static option from dropdown' do
+ find("#js-dropdown-milestone").find('.filter-dropdown-item', text: 'Upcoming').click
+
+ expect(first('.tokens-container .filtered-search-token .value').text).to eq('upcoming')
+ expect(is_input_focused).to eq(true)
+ end
+
+ it 'makes value editable' do
+ expect_filtered_search_input('%10.0')
+ end
+
+ it 'filters value' do
+ filtered_search.send_keys(:backspace)
+
+ expect(page).to have_css('#js-dropdown-milestone .filter-dropdown .filter-dropdown-item', count: 1)
+ end
+
+ it 'ends editing mode when document is clicked' do
+ find('#content-body').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-milestone', visible: false)
+ end
+
+ it 'ends editing mode when scroll container is clicked' do
+ find('.scroll-container').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-milestone', visible: false)
+ end
+ end
+
+ describe 'editing label token' do
+ before do
+ input_filtered_search("label:~#{label.title} author:none", submit: false)
+ first('.tokens-container .filtered-search-token').double_click
+ first('#js-dropdown-label .filter-dropdown .filter-dropdown-item')
+ end
+
+ it 'opens label dropdown' do
+ expect(filter_label_dropdown.find('.filter-dropdown-item', text: label.title)).to be_visible
+ expect(filter_label_dropdown.find('.filter-dropdown-item', text: cc_label.title)).to be_visible
+ expect(page).to have_css('#js-dropdown-label', visible: true)
+ end
+
+ it 'selects option from dropdown' do
+ expect(filter_label_dropdown.find('.filter-dropdown-item', text: label.title)).to be_visible
+ expect(filter_label_dropdown.find('.filter-dropdown-item', text: cc_label.title)).to be_visible
+
+ find("#js-dropdown-label").find('.filter-dropdown-item', text: cc_label.title).click
+
+ expect(first('.tokens-container .filtered-search-token .value').text).to eq("~\"#{cc_label.title}\"")
+ expect(is_input_focused).to eq(true)
+ end
+
+ it 'makes value editable' do
+ expect_filtered_search_input("~#{label.title}")
+ end
+
+ it 'filters value' do
+ expect(filter_label_dropdown.find('.filter-dropdown-item', text: label.title)).to be_visible
+ expect(filter_label_dropdown.find('.filter-dropdown-item', text: cc_label.title)).to be_visible
+
+ filtered_search.send_keys(:backspace)
+
+ filter_label_dropdown.find('.filter-dropdown-item')
+
+ expect(page.all('#js-dropdown-label .filter-dropdown .filter-dropdown-item').size).to eq(1)
+ end
+
+ it 'ends editing mode when document is clicked' do
+ find('#content-body').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-label', visible: false)
+ end
+
+ it 'ends editing mode when scroll container is clicked' do
+ find('.scroll-container').click
+
+ expect_filtered_search_input_empty
+ expect(page).to have_css('#js-dropdown-label', visible: false)
+ end
+ end
+
+ describe 'add new token after editing existing token' do
+ before do
+ input_filtered_search('author:@root assignee:none', submit: false)
+ first('.tokens-container .filtered-search-token').double_click
+ filtered_search.send_keys(' ')
+ end
+
+ describe 'opens dropdowns' do
+ it 'opens hint dropdown' do
+ expect(page).to have_css('#js-dropdown-hint', visible: true)
+ end
+
+ it 'opens author dropdown' do
+ filtered_search.send_keys('author:')
+ expect(page).to have_css('#js-dropdown-author', visible: true)
+ end
+
+ it 'opens assignee dropdown' do
+ filtered_search.send_keys('assignee:')
+ expect(page).to have_css('#js-dropdown-assignee', visible: true)
+ end
+
+ it 'opens milestone dropdown' do
+ filtered_search.send_keys('milestone:')
+ expect(page).to have_css('#js-dropdown-milestone', visible: true)
+ end
+
+ it 'opens label dropdown' do
+ filtered_search.send_keys('label:')
+ expect(page).to have_css('#js-dropdown-label', visible: true)
+ end
+ end
+
+ describe 'creates visual tokens' do
+ it 'creates author token' do
+ filtered_search.send_keys('author:@thomas ')
+ token = page.all('.tokens-container .filtered-search-token')[1]
+
+ expect(token.find('.name').text).to eq('Author')
+ expect(token.find('.value').text).to eq('@thomas')
+ end
+
+ it 'creates assignee token' do
+ filtered_search.send_keys('assignee:@thomas ')
+ token = page.all('.tokens-container .filtered-search-token')[1]
+
+ expect(token.find('.name').text).to eq('Assignee')
+ expect(token.find('.value').text).to eq('@thomas')
+ end
+
+ it 'creates milestone token' do
+ filtered_search.send_keys('milestone:none ')
+ token = page.all('.tokens-container .filtered-search-token')[1]
+
+ expect(token.find('.name').text).to eq('Milestone')
+ expect(token.find('.value').text).to eq('none')
+ end
+
+ it 'creates label token' do
+ filtered_search.send_keys('label:~Backend ')
+ token = page.all('.tokens-container .filtered-search-token')[1]
+
+ expect(token.find('.name').text).to eq('Label')
+ expect(token.find('.value').text).to eq('~Backend')
+ end
+ end
+
+ it 'does not tokenize incomplete token' do
+ filtered_search.send_keys('author:')
+
+ find('#content-body').click
+ token = page.all('.tokens-container .js-visual-token')[1]
+
+ expect_filtered_search_input_empty
+ expect(token.find('.name').text).to eq('Author')
+ end
+ end
+end