diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
index 45aa6050aed3453d5a2c7fd1fd8b558e823cd5e8..f55db02f0fd2b4f1c4db1a756bfdd455c45a7ccf 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -74,7 +74,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
         case 'projects:merge_requests:index':
         case 'projects:issues:index':
           if (gl.FilteredSearchManager) {
-            new gl.FilteredSearchManager();
+            new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests');
           }
           Issuable.init();
           new gl.IssuableBulkActions({
diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
index 572c221929a72f747310f0066f6818cc42ac5c9d..9e92d544bef816ff6c3595efed759b1aa6e96b76 100644
--- a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
@@ -37,23 +37,18 @@ require('./filtered_search_dropdown');
     }
 
     renderContent() {
-      const dropdownData = [{
-        icon: 'fa-pencil',
-        hint: 'author:',
-        tag: '<@author>',
-      }, {
-        icon: 'fa-user',
-        hint: 'assignee:',
-        tag: '<@assignee>',
-      }, {
-        icon: 'fa-clock-o',
-        hint: 'milestone:',
-        tag: '<%milestone>',
-      }, {
-        icon: 'fa-tag',
-        hint: 'label:',
-        tag: '<~label>',
-      }];
+      const dropdownData = [];
+
+      [].forEach.call(this.input.parentElement.querySelectorAll('.dropdown-menu'), (dropdownMenu) => {
+        const { icon, hint, tag } = dropdownMenu.dataset;
+        if (icon && hint && tag) {
+          dropdownData.push({
+            icon: `fa-${icon}`,
+            hint,
+            tag: `<${tag}>`,
+          });
+        }
+      });
 
       this.droplab.changeHookList(this.hookId, this.dropdown, [droplabFilter], this.config);
       this.droplab.setData(this.hookId, dropdownData);
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
index e8c2df03a4653ffd51ba470e65b5b50f52012a42..fbc72a3001a0aa125866bf5d144dc21b6b63da31 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
@@ -52,8 +52,9 @@
     }
 
     renderContent(forceShowList = false) {
-      if (forceShowList && this.getCurrentHook().list.hidden) {
-        this.getCurrentHook().list.show();
+      const currentHook = this.getCurrentHook();
+      if (forceShowList && currentHook && currentHook.list.hidden) {
+        currentHook.list.show();
       }
     }
 
@@ -92,18 +93,24 @@
     }
 
     hideDropdown() {
-      this.getCurrentHook().list.hide();
+      const currentHook = this.getCurrentHook();
+      if (currentHook) {
+        currentHook.list.hide();
+      }
     }
 
     resetFilters() {
       const hook = this.getCurrentHook();
-      const data = hook.list.data;
-      const results = data.map((o) => {
-        const updated = o;
-        updated.droplab_hidden = false;
-        return updated;
-      });
-      hook.list.render(results);
+
+      if (hook) {
+        const data = hook.list.data;
+        const results = data.map((o) => {
+          const updated = o;
+          updated.droplab_hidden = false;
+          return updated;
+        });
+        hook.list.render(results);
+      }
     }
   }
 
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
index 8ce4cf4fc360ce8a3789b6b966254d1adcd57019..cecd3518ce3f5d89514f458f6c594ab728b0a007 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
@@ -2,10 +2,12 @@
 
 (() => {
   class FilteredSearchDropdownManager {
-    constructor(baseEndpoint = '') {
+    constructor(baseEndpoint = '', page) {
       this.baseEndpoint = baseEndpoint.replace(/\/$/, '');
       this.tokenizer = gl.FilteredSearchTokenizer;
+      this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeys;
       this.filteredSearchInput = document.querySelector('.filtered-search');
+      this.page = page;
 
       this.setupMapping();
 
@@ -150,7 +152,7 @@
         this.droplab = new DropLab();
       }
 
-      const match = gl.FilteredSearchTokenKeys.searchByKey(dropdownName.toLowerCase());
+      const match = this.filteredSearchTokenKeys.searchByKey(dropdownName.toLowerCase());
       const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key
         && this.mapping[match.key];
       const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
index 13a9bf592465dc9fd9c3f32e37eb442135db4842..bbafead03054222a85446326e17b288ab48c7287 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
@@ -1,12 +1,13 @@
 (() => {
   class FilteredSearchManager {
-    constructor() {
+    constructor(page) {
       this.filteredSearchInput = document.querySelector('.filtered-search');
       this.clearSearchButton = document.querySelector('.clear-search');
+      this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeys;
 
       if (this.filteredSearchInput) {
         this.tokenizer = gl.FilteredSearchTokenizer;
-        this.dropdownManager = new gl.FilteredSearchDropdownManager(this.filteredSearchInput.getAttribute('data-base-endpoint') || '');
+        this.dropdownManager = new gl.FilteredSearchDropdownManager(this.filteredSearchInput.getAttribute('data-base-endpoint') || '', page);
 
         this.bindEvents();
         this.loadSearchParamsFromURL();
@@ -117,8 +118,8 @@
         const keyParam = decodeURIComponent(split[0]);
         const value = split[1];
 
-        // Check if it matches edge conditions listed in gl.FilteredSearchTokenKeys
-        const condition = gl.FilteredSearchTokenKeys.searchByConditionUrl(p);
+        // Check if it matches edge conditions listed in this.filteredSearchTokenKeys
+        const condition = this.filteredSearchTokenKeys.searchByConditionUrl(p);
 
         if (condition) {
           inputValues.push(`${condition.tokenKey}:${condition.value}`);
@@ -126,7 +127,7 @@
           // Sanitize value since URL converts spaces into +
           // Replace before decode so that we know what was originally + versus the encoded +
           const sanitizedValue = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : value;
-          const match = gl.FilteredSearchTokenKeys.searchByKeyParam(keyParam);
+          const match = this.filteredSearchTokenKeys.searchByKeyParam(keyParam);
 
           if (match) {
             const indexOf = keyParam.indexOf('_');
@@ -171,9 +172,9 @@
       paths.push(`state=${currentState}`);
 
       tokens.forEach((token) => {
-        const condition = gl.FilteredSearchTokenKeys
+        const condition = this.filteredSearchTokenKeys
           .searchByConditionKeyValue(token.key, token.value.toLowerCase());
-        const { param } = gl.FilteredSearchTokenKeys.searchByKey(token.key) || {};
+        const { param } = this.filteredSearchTokenKeys.searchByKey(token.key) || {};
         const keyParam = param ? `${token.key}_${param}` : token.key;
         let tokenPath = '';
 
diff --git a/app/assets/javascripts/search_autocomplete.js.es6 b/app/assets/javascripts/search_autocomplete.js.es6
index 6250e75d407e76aac8e9f8d13f611524195c06f7..6fd5345a0a6a4ead3b510d55ee62459d9d9b69b8 100644
--- a/app/assets/javascripts/search_autocomplete.js.es6
+++ b/app/assets/javascripts/search_autocomplete.js.es6
@@ -169,10 +169,10 @@
           url: issuesPath + "/?author_username=" + userName
         }, 'separator', {
           text: 'Merge requests assigned to me',
-          url: mrPath + "/?assignee_id=" + userId
+          url: mrPath + "/?assignee_username=" + userName
         }, {
           text: "Merge requests I've created",
-          url: mrPath + "/?author_id=" + userId
+          url: mrPath + "/?author_username=" + userName
         }
       ];
       if (!name) {
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 2bf3542d089e57eb047e013d1ccdad719d9496b1..75971faa93e6475609b49fb1854a1fce1bda24e1 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -50,6 +50,17 @@ class Projects::MergeRequestsController < Projects::ApplicationController
       @labels = LabelsFinder.new(current_user, labels_params).execute
     end
 
+    @users = []
+    if params[:assignee_id].present?
+      assignee = User.find_by_id(params[:assignee_id])
+      @users.push(assignee) if assignee
+    end
+
+    if params[:author_id].present?
+      author = User.find_by_id(params[:author_id])
+      @users.push(author) if author
+    end
+
     respond_to do |format|
       format.html
       format.json do
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 144b3a9c8c85d59096be1972348ac93f98455dcf..83e6c026ba7deb2da3c7e7bade1d13e3c003ab5f 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -5,18 +5,19 @@
 = render "projects/issues/head"
 = render 'projects/last_push'
 
+- content_for :page_specific_javascripts do
+  = page_specific_javascript_bundle_tag('filtered_search')
+
 %div{ class: container_class }
   .top-area
     = render 'shared/issuable/nav', type: :merge_requests
     .nav-controls
-      = render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
-
       - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
       - if merge_project
         = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do
           New Merge Request
 
-  = render 'shared/issuable/filter', type: :merge_requests
+  = render 'shared/issuable/search_bar', type: :merge_requests
 
   .merge-requests-holder
     = render 'merge_requests'
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 6e417aa2251ddcb633bbbb647d524ea0068172e6..8e04b50bb8ac1a535ab181ac9794775563f7798c 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -32,7 +32,7 @@
                     {{hint}}
                   %span.js-filter-tag.dropdown-light-content
                     {{tag}}
-          #js-dropdown-author.dropdown-menu
+          #js-dropdown-author.dropdown-menu{ data: { icon: 'pencil', hint: 'author', tag: '@author' } }
             %ul.filter-dropdown{ 'data-dynamic' => true, 'data-dropdown' => true }
               %li.filter-dropdown-item
                 %button.btn.btn-link.dropdown-user
@@ -42,7 +42,7 @@
                       {{name}}
                     %span.dropdown-light-content
                       @{{username}}
-          #js-dropdown-assignee.dropdown-menu
+          #js-dropdown-assignee.dropdown-menu{ data: { icon: 'user', hint: 'assignee', tag: '@assignee' } }
             %ul{ 'data-dropdown' => true }
               %li.filter-dropdown-item{ 'data-value' => 'none' }
                 %button.btn.btn-link
@@ -57,7 +57,7 @@
                       {{name}}
                     %span.dropdown-light-content
                       @{{username}}
-          #js-dropdown-milestone.dropdown-menu{ 'data-dropdown' => true }
+          #js-dropdown-milestone.dropdown-menu{ data: { icon: 'clock-o', hint: 'milestone', tag: '%milestone' } }
             %ul{ 'data-dropdown' => true }
               %li.filter-dropdown-item{ 'data-value' => 'none' }
                 %button.btn.btn-link
@@ -70,7 +70,7 @@
               %li.filter-dropdown-item
                 %button.btn.btn-link.js-data-value
                   {{title}}
-          #js-dropdown-label.dropdown-menu{ 'data-dropdown' => true }
+          #js-dropdown-label.dropdown-menu{ data: { icon: 'tag', hint: 'label', tag: '~label' } }
             %ul{ 'data-dropdown' => true }
               %li.filter-dropdown-item{ 'data-value' => 'none' }
                 %button.btn.btn-link
diff --git a/changelogs/unreleased/add-filtered-search-to-mr.yml b/changelogs/unreleased/add-filtered-search-to-mr.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e3577e2aec71cc89af516887d485ef60e1d6cb3c
--- /dev/null
+++ b/changelogs/unreleased/add-filtered-search-to-mr.yml
@@ -0,0 +1,4 @@
+---
+title: Add filtered search to MR page
+merge_request:
+author:
diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature
index 5aa592e9067ccc9d8cc9f49af8c0e46535b06ad8..bcde497553bea5cfebc1daf696b5ea3d00c31cce 100644
--- a/features/project/merge_requests.feature
+++ b/features/project/merge_requests.feature
@@ -293,13 +293,6 @@ Feature: Project Merge Requests
     And I preview a description text like "Bug fixed :smile:"
     Then I should see the Markdown write tab
 
-  @javascript
-  Scenario: I search merge request
-    Given I click link "All"
-    When I fill in merge request search with "Fe"
-    Then I should see "Feature NS-03" in merge requests
-    And I should not see "Bug NS-04" in merge requests
-
   @javascript
   Scenario: I can unsubscribe from merge request
     Given I visit merge request page "Bug NS-04"
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index c6a88e1b7b0554c1b4ac01cf068f94fd5d622644..ab3b868fd3a7315ee2f0227ac99a806180613534 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -1,6 +1,8 @@
 require 'spec_helper'
 
 describe 'Dropdown label', js: true, feature: true do
+  include FilteredSearchHelpers
+
   let(:project) { create(:empty_project) }
   let(:user) { create(:user) }
   let(:filtered_search) { find('.filtered-search') }
@@ -17,12 +19,6 @@ describe 'Dropdown label', js: true, feature: true do
     let!(:long_label) { create(:label, project: project, title: 'this is a very long title this is a very long title this is a very long title this is a very long title this is a very long title') }
   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 search_for_label(label)
     init_label_search
     filtered_search.send_keys(label)
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 64f448a83b79ec90de6b19d0529b87ac61c20333..0420e64d42c4bf46460f77aa19761649fc60e648 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -1,6 +1,7 @@
 require 'rails_helper'
 
 describe 'Filter issues', js: true, feature: true do
+  include FilteredSearchHelpers
   include WaitForAjax
 
   let!(:group) { create(:group) }
@@ -17,19 +18,6 @@ describe 'Filter issues', js: true, feature: true do
   let!(:multiple_words_label) { create(:label, project: project, title: "Two words") }
 
   let!(:closed_issue) { create(:issue, title: 'bug that is closed', project: project, state: :closed) }
-  let(:filtered_search) { find('.filtered-search') }
-
-  def input_filtered_search(search_term, submit: true)
-    filtered_search.set(search_term)
-
-    if submit
-      filtered_search.send_keys(:enter)
-    end
-  end
-
-  def expect_filtered_search_input(input)
-    expect(find('.filtered-search').value).to eq(input)
-  end
 
   def expect_no_issues_list
     page.within '.issues-list' do
diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb
index 4c60329865cf7c64ec2937202331ca43096004ea..55f3c1863ff173ed95ba21cf2f180d656c429f0c 100644
--- a/spec/features/merge_requests/filter_by_labels_spec.rb
+++ b/spec/features/merge_requests/filter_by_labels_spec.rb
@@ -1,6 +1,8 @@
 require 'rails_helper'
 
 feature 'Issue filtering by Labels', feature: true, js: true do
+  include FilteredSearchHelpers
+  include MergeRequestHelpers
   include WaitForAjax
 
   let(:project) { create(:project, :public) }
@@ -32,123 +34,77 @@ feature 'Issue filtering by Labels', feature: true, js: true do
 
   context 'filter by label bug' do
     before do
-      select_labels('bug')
+      input_filtered_search('label:~bug')
     end
 
     it 'apply the filter' do
       expect(page).to have_content "Bugfix1"
       expect(page).to have_content "Bugfix2"
       expect(page).not_to have_content "Feature1"
-      expect(find('.filtered-labels')).to have_content "bug"
-      expect(find('.filtered-labels')).not_to have_content "feature"
-      expect(find('.filtered-labels')).not_to have_content "enhancement"
-
-      find('.js-label-filter-remove').click
-      wait_for_ajax
-      expect(find('.filtered-labels', visible: false)).to have_no_content "bug"
     end
   end
 
   context 'filter by label feature' do
     before do
-      select_labels('feature')
+      input_filtered_search('label:~feature')
     end
 
     it 'applies the filter' do
       expect(page).to have_content "Feature1"
       expect(page).not_to have_content "Bugfix2"
       expect(page).not_to have_content "Bugfix1"
-      expect(find('.filtered-labels')).to have_content "feature"
-      expect(find('.filtered-labels')).not_to have_content "bug"
-      expect(find('.filtered-labels')).not_to have_content "enhancement"
     end
   end
 
   context 'filter by label enhancement' do
     before do
-      select_labels('enhancement')
+      input_filtered_search('label:~enhancement')
     end
 
     it 'applies the filter' do
       expect(page).to have_content "Bugfix2"
       expect(page).not_to have_content "Feature1"
       expect(page).not_to have_content "Bugfix1"
-      expect(find('.filtered-labels')).to have_content "enhancement"
-      expect(find('.filtered-labels')).not_to have_content "bug"
-      expect(find('.filtered-labels')).not_to have_content "feature"
     end
   end
 
   context 'filter by label enhancement and bug in issues list' do
     before do
-      select_labels('bug', 'enhancement')
+      input_filtered_search('label:~bug label:~enhancement')
     end
 
     it 'applies the filters' do
       expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
       expect(page).to have_content "Bugfix2"
       expect(page).not_to have_content "Feature1"
-      expect(find('.filtered-labels')).to have_content "bug"
-      expect(find('.filtered-labels')).to have_content "enhancement"
-      expect(find('.filtered-labels')).not_to have_content "feature"
-
-      find('.js-label-filter-remove', match: :first).click
-      wait_for_ajax
-
-      expect(page).to have_content "Bugfix2"
-      expect(page).not_to have_content "Feature1"
-      expect(page).not_to have_content "Bugfix1"
-      expect(find('.filtered-labels')).not_to have_content "bug"
-      expect(find('.filtered-labels')).to have_content "enhancement"
-      expect(find('.filtered-labels')).not_to have_content "feature"
     end
   end
 
-  context 'remove filtered labels' do
+  context 'clear button' do
     before do
-      page.within '.labels-filter' do
-        click_button 'Label'
-        wait_for_ajax
-        click_link 'bug'
-        find('.dropdown-menu-close').click
-      end
-
-      page.within '.filtered-labels' do
-        expect(page).to have_content 'bug'
-      end
+      input_filtered_search('label:~bug')
     end
 
     it 'allows user to remove filtered labels' do
-      first('.js-label-filter-remove').click
-      wait_for_ajax
+      first('.clear-search').click
+      filtered_search.send_keys(:enter)
 
-      expect(find('.filtered-labels', visible: false)).not_to have_content 'bug'
-      expect(find('.labels-filter')).not_to have_content 'bug'
+      expect(page).to have_issuable_counts(open: 3, closed: 0, all: 3)
+      expect(page).to have_content "Bugfix2"
+      expect(page).to have_content "Feature1"
+      expect(page).to have_content "Bugfix1"
     end
   end
 
-  context 'dropdown filtering' do
+  context 'filter dropdown' do
     it 'filters by label name' do
-      page.within '.labels-filter' do
-        click_button 'Label'
-        wait_for_ajax
-        find('.dropdown-input input').set 'bug'
-
-        page.within '.dropdown-content' do
-          expect(page).not_to have_content 'enhancement'
-          expect(page).to have_content 'bug'
-        end
-      end
-    end
-  end
+      init_label_search
+      filtered_search.send_keys('~bug')
 
-  def select_labels(*labels)
-    page.find('.js-label-select').click
-    wait_for_ajax
-    labels.each do |label|
-      execute_script("$('.dropdown-menu-labels li:contains(\"#{label}\") a').click()")
+      page.within '.filter-dropdown' do
+        expect(page).not_to have_content 'enhancement'
+        expect(page).to have_content 'bug'
+      end
     end
-    page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
-    wait_for_ajax
   end
 end
diff --git a/spec/features/merge_requests/filter_by_milestone_spec.rb b/spec/features/merge_requests/filter_by_milestone_spec.rb
index f6e9230c8dad26b93514e8bccfa5ee0e44d09f56..5608cda28f8601b4cae87d01fcd817ac4f1db882 100644
--- a/spec/features/merge_requests/filter_by_milestone_spec.rb
+++ b/spec/features/merge_requests/filter_by_milestone_spec.rb
@@ -1,10 +1,18 @@
 require 'rails_helper'
 
 feature 'Merge Request filtering by Milestone', feature: true do
+  include FilteredSearchHelpers
+  include MergeRequestHelpers
+
   let(:project)   { create(:project, :public) }
   let!(:user)     { create(:user)}
   let(:milestone) { create(:milestone, project: project) }
 
+  def filter_by_milestone(title)
+    find(".js-milestone-select").click
+    find(".milestone-filter a", text: title).click
+  end
+
   before do
     project.team << [user, :master]
     login_as(user)
@@ -15,42 +23,42 @@ feature 'Merge Request filtering by Milestone', feature: true do
     create(:merge_request, :simple, source_project: project, milestone: milestone)
 
     visit_merge_requests(project)
-    filter_by_milestone(Milestone::None.title)
+    input_filtered_search('milestone:none')
 
     expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
     expect(page).to have_css('.merge-request', count: 1)
   end
 
   context 'filters by upcoming milestone', js: true do
-    it 'does not show issues with no expiry' do
+    it 'does not show merge requests with no expiry' do
       create(:merge_request, :with_diffs, source_project: project)
       create(:merge_request, :simple, source_project: project, milestone: milestone)
 
       visit_merge_requests(project)
-      filter_by_milestone(Milestone::Upcoming.title)
+      input_filtered_search('milestone:upcoming')
 
       expect(page).to have_css('.merge-request', count: 0)
     end
 
-    it 'shows issues in future' do
+    it 'shows merge requests in future' do
       milestone = create(:milestone, project: project, due_date: Date.tomorrow)
       create(:merge_request, :with_diffs, source_project: project)
       create(:merge_request, :simple, source_project: project, milestone: milestone)
 
       visit_merge_requests(project)
-      filter_by_milestone(Milestone::Upcoming.title)
+      input_filtered_search('milestone:upcoming')
 
       expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
       expect(page).to have_css('.merge-request', count: 1)
     end
 
-    it 'does not show issues in past' do
+    it 'does not show merge requests in past' do
       milestone = create(:milestone, project: project, due_date: Date.yesterday)
       create(:merge_request, :with_diffs, source_project: project)
       create(:merge_request, :simple, source_project: project, milestone: milestone)
 
       visit_merge_requests(project)
-      filter_by_milestone(Milestone::Upcoming.title)
+      input_filtered_search('milestone:upcoming')
 
       expect(page).to have_css('.merge-request', count: 0)
     end
@@ -61,7 +69,7 @@ feature 'Merge Request filtering by Milestone', feature: true do
     create(:merge_request, :simple, source_project: project)
 
     visit_merge_requests(project)
-    filter_by_milestone(milestone.title)
+    input_filtered_search("milestone:%'#{milestone.title}'")
 
     expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
     expect(page).to have_css('.merge-request', count: 1)
@@ -77,19 +85,10 @@ feature 'Merge Request filtering by Milestone', feature: true do
       create(:merge_request, :simple, source_project: project)
 
       visit_merge_requests(project)
-      filter_by_milestone(milestone.title)
+      input_filtered_search("milestone:%\"#{milestone.title}\"")
 
       expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
       expect(page).to have_css('.merge-request', count: 1)
     end
   end
-
-  def visit_merge_requests(project)
-    visit namespace_project_merge_requests_path(project.namespace, project)
-  end
-
-  def filter_by_milestone(title)
-    find(".js-milestone-select").click
-    find(".milestone-filter a", text: title).click
-  end
 end
diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb
index 4642b5a530d1c2ec3b0913dd089ca63b9945a81f..6579a88d4ab15266d2578839aed57345ef67c3d4 100644
--- a/spec/features/merge_requests/filter_merge_requests_spec.rb
+++ b/spec/features/merge_requests/filter_merge_requests_spec.rb
@@ -1,11 +1,13 @@
 require 'rails_helper'
 
 describe 'Filter merge requests', feature: true do
+  include FilteredSearchHelpers
+  include MergeRequestHelpers
   include WaitForAjax
 
   let!(:project)   { create(:project) }
   let!(:group)     { create(:group) }
-  let!(:user)      { create(:user)}
+  let!(:user)      { create(:user) }
   let!(:milestone) { create(:milestone, project: project) }
   let!(:label)     { create(:label, project: project) }
   let!(:wontfix)   { create(:label, project: project, title: "Won't fix") }
@@ -15,183 +17,134 @@ describe 'Filter merge requests', feature: true do
     group.add_developer(user)
     login_as(user)
     create(:merge_request, source_project: project, target_project: project)
+
+    visit namespace_project_merge_requests_path(project.namespace, project)
   end
 
   describe 'for assignee from mr#index' do
-    before do
-      visit namespace_project_merge_requests_path(project.namespace, project)
+    let(:search_query) { "assignee:@#{user.username}" }
 
-      find('.js-assignee-search').click
-
-      find('.dropdown-menu-user-link', text: user.username).click
+    before do
+      input_filtered_search(search_query)
 
-      wait_for_ajax
+      expect_mr_list_count(0)
     end
 
     context 'assignee', js: true do
       it 'updates to current user' do
-        expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
+        expect_filtered_search_input(search_query)
       end
 
       it 'does not change when closed link is clicked' do
         find('.issues-state-filters a', text: "Closed").click
 
-        expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
+        expect_filtered_search_input(search_query)
       end
 
       it 'does not change when all link is clicked' do
         find('.issues-state-filters a', text: "All").click
 
-        expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
+        expect_filtered_search_input(search_query)
       end
     end
   end
 
   describe 'for milestone from mr#index' do
-    before do
-      visit namespace_project_merge_requests_path(project.namespace, project)
-
-      find('.js-milestone-select').click
+    let(:search_query) { "milestone:%#{milestone.title}" }
 
-      find('.milestone-filter .dropdown-content a', text: milestone.title).click
+    before do
+      input_filtered_search(search_query)
 
-      wait_for_ajax
+      expect_mr_list_count(0)
     end
 
     context 'milestone', js: true do
       it 'updates to current milestone' do
-        expect(find('.js-milestone-select .dropdown-toggle-text')).to have_content(milestone.title)
+        expect_filtered_search_input(search_query)
       end
 
       it 'does not change when closed link is clicked' do
         find('.issues-state-filters a', text: "Closed").click
 
-        expect(find('.js-milestone-select .dropdown-toggle-text')).to have_content(milestone.title)
+        expect_filtered_search_input(search_query)
       end
 
       it 'does not change when all link is clicked' do
         find('.issues-state-filters a', text: "All").click
 
-        expect(find('.js-milestone-select .dropdown-toggle-text')).to have_content(milestone.title)
+        expect_filtered_search_input(search_query)
       end
     end
   end
 
   describe 'for label from mr#index', js: true do
-    before do
-      visit namespace_project_merge_requests_path(project.namespace, project)
-      find('.js-label-select').click
-      wait_for_ajax
-    end
-
-    it 'filters by any label' do
-      find('.dropdown-menu-labels a', text: 'Any Label').click
-      page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
-      wait_for_ajax
-
-      expect(find('.labels-filter')).to have_content 'Label'
-    end
-
     it 'filters by no label' do
-      find('.dropdown-menu-labels a', text: 'No Label').click
-      page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
-      wait_for_ajax
+      input_filtered_search('label:none')
 
-      page.within '.labels-filter' do
-        expect(page).to have_content 'Labels'
-      end
-      expect(find('.js-label-select .dropdown-toggle-text')).to have_content('Labels')
+      expect_mr_list_count(1)
+      expect_filtered_search_input('label:none')
     end
 
     it 'filters by a label' do
-      find('.dropdown-menu-labels a', text: label.title).click
-      page.within '.labels-filter' do
-        expect(page).to have_content label.title
-      end
-      expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title)
+      input_filtered_search("label:~#{label.title}")
+
+      expect_mr_list_count(0)
+      expect_filtered_search_input("label:~#{label.title}")
     end
 
     it "filters by `won't fix` and another label" do
-      page.within '.labels-filter' do
-        click_link wontfix.title
-        expect(page).to have_content wontfix.title
-        click_link label.title
-      end
+      input_filtered_search("label:~\"#{wontfix.title}\" label:~#{label.title}")
 
-      expect(find('.js-label-select .dropdown-toggle-text')).to have_content("#{wontfix.title} +1 more")
+      expect_mr_list_count(0)
+      expect_filtered_search_input("label:~\"#{wontfix.title}\" label:~#{label.title}")
     end
 
     it "filters by `won't fix` label followed by another label after page load" do
-      page.within '.labels-filter' do
-        click_link wontfix.title
-        expect(page).to have_content wontfix.title
-      end
-
-      find('body').click
-
-      expect(find('.filtered-labels')).to have_content(wontfix.title)
-
-      find('.js-label-select').click
-      wait_for_ajax
-      find('.dropdown-menu-labels a', text: label.title).click
-
-      find('body').click
+      input_filtered_search("label:~\"#{wontfix.title}\"")
 
-      expect(find('.filtered-labels')).to have_content(wontfix.title)
-      expect(find('.filtered-labels')).to have_content(label.title)
+      expect_mr_list_count(0)
+      expect_filtered_search_input("label:~\"#{wontfix.title}\"")
 
-      find('.js-label-select').click
-      wait_for_ajax
+      input_filtered_search_keys(" label:~#{label.title}")
 
-      expect(find('.dropdown-menu-labels li', text: wontfix.title)).to have_css('.is-active')
-      expect(find('.dropdown-menu-labels li', text: label.title)).to have_css('.is-active')
-    end
+      expect_filtered_search_input("label:~\"#{wontfix.title}\" label:~#{label.title}")
 
-    it "selects and unselects `won't fix`" do
-      find('.dropdown-menu-labels a', text: wontfix.title).click
-      find('.dropdown-menu-labels a', text: wontfix.title).click
-      # Close label dropdown to load
-      find('body').click
-      expect(page).not_to have_css('.filtered-labels')
+      expect_mr_list_count(0)
+      expect_filtered_search_input("label:~\"#{wontfix.title}\" label:~#{label.title}")
     end
   end
 
   describe 'for assignee and label from issues#index' do
-    before do
-      visit namespace_project_merge_requests_path(project.namespace, project)
-
-      find('.js-assignee-search').click
+    let(:search_query) { "assignee:@#{user.username} label:~#{label.title}" }
 
-      find('.dropdown-menu-user-link', text: user.username).click
+    before do
+      input_filtered_search("assignee:@#{user.username}")
 
-      expect(page).not_to have_selector('.mr-list .merge-request')
+      expect_mr_list_count(1)
+      expect_filtered_search_input("assignee:@#{user.username}")
 
-      find('.js-label-select').click
+      input_filtered_search_keys(" label:~#{label.title}")
 
-      find('.dropdown-menu-labels .dropdown-content a', text: label.title).click
-      page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
+      expect_mr_list_count(1)
 
-      wait_for_ajax
+      find("#state-opened[href=\"#{URI.parse(current_url).path}?assignee_username=#{user.username}&label_name%5B%5D=#{label.title}&scope=all&state=opened\"]")
     end
 
     context 'assignee and label', js: true do
       it 'updates to current assignee and label' do
-        expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
-        expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title)
+        expect_filtered_search_input(search_query)
       end
 
       it 'does not change when closed link is clicked' do
         find('.issues-state-filters a', text: "Closed").click
 
-        expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
-        expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title)
+        expect_filtered_search_input(search_query)
       end
 
       it 'does not change when all link is clicked' do
         find('.issues-state-filters a', text: "All").click
 
-        expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
-        expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title)
+        expect_filtered_search_input(search_query)
       end
     end
   end
@@ -203,11 +156,11 @@ describe 'Filter merge requests', feature: true do
       bug_label = create(:label, project: project, title: 'bug')
       milestone = create(:milestone, title: "8", project: project)
 
-      mr = create(:merge_request, 
-        title: "Bug 2", 
-        source_project: project, 
-        target_project: project, 
-        source_branch: "bug2", 
+      mr = create(:merge_request,
+        title: "Bug 2",
+        source_project: project,
+        target_project: project,
+        source_branch: "bug2",
         milestone: milestone,
         author: user,
         assignee: user)
@@ -218,15 +171,13 @@ describe 'Filter merge requests', feature: true do
 
     context 'only text', js: true do
       it 'filters merge requests by searched text' do
-        fill_in 'issuable_search', with: 'Bug'
+        input_filtered_search('bug')
 
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 2)
-        end
+        expect_mr_list_count(2)
       end
 
       it 'does not show any merge requests' do
-        fill_in 'issuable_search', with: 'testing'
+        input_filtered_search('testing')
 
         page.within '.mr-list' do
           expect(page).not_to have_selector('.merge-request')
@@ -234,82 +185,49 @@ describe 'Filter merge requests', feature: true do
       end
     end
 
-    context 'text and dropdown options', js: true do
+    context 'filters and searches', js: true do
       it 'filters by text and label' do
-        fill_in 'issuable_search', with: 'Bug'
+        input_filtered_search('Bug')
 
-        expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 2)
-        end
+        expect_mr_list_count(2)
+        expect_filtered_search_input('Bug')
 
-        click_button 'Label'
-        page.within '.labels-filter' do
-          click_link 'bug'
-        end
-        find('.dropdown-menu-close-icon').click
+        input_filtered_search_keys(' label:~bug')
 
-        expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 1)
-        end
+        expect_mr_list_count(1)
       end
 
       it 'filters by text and milestone' do
-        fill_in 'issuable_search', with: 'Bug'
+        input_filtered_search('Bug')
 
-        expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 2)
-        end
+        expect_mr_list_count(2)
+        expect_filtered_search_input('Bug')
 
-        click_button 'Milestone'
-        page.within '.milestone-filter' do
-          click_link '8'
-        end
+        input_filtered_search_keys(' milestone:%8')
 
-        expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 1)
-        end
+        expect_mr_list_count(1)
       end
 
       it 'filters by text and assignee' do
-        fill_in 'issuable_search', with: 'Bug'
+        input_filtered_search('Bug')
 
-        expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 2)
-        end
+        expect_mr_list_count(2)
+        expect_filtered_search_input('Bug')
 
-        click_button 'Assignee'
-        page.within '.dropdown-menu-assignee' do
-          click_link user.name
-        end
+        input_filtered_search_keys(" assignee:@#{user.username}")
 
-        expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 1)
-        end
+        expect_mr_list_count(1)
       end
 
       it 'filters by text and author' do
-        fill_in 'issuable_search', with: 'Bug'
+        input_filtered_search('Bug')
 
-        expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 2)
-        end
+        expect_mr_list_count(2)
+        expect_filtered_search_input('Bug')
 
-        click_button 'Author'
-        page.within '.dropdown-menu-author' do
-          click_link user.name
-        end
+        input_filtered_search_keys(" author:@#{user.username}")
 
-        expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
-        page.within '.mr-list' do
-          expect(page).to have_selector('.merge-request', count: 1)
-        end
+        expect_mr_list_count(1)
       end
     end
   end
@@ -328,18 +246,9 @@ describe 'Filter merge requests', feature: true do
     end
 
     it 'is able to filter and sort merge requests' do
-      click_button 'Label'
-      wait_for_ajax
-      page.within '.labels-filter' do
-        click_link 'bug'
-      end
-      find('.dropdown-menu-close-icon').click
-      wait_for_ajax
+      input_filtered_search('label:~bug')
 
-      expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
-      page.within '.mr-list' do
-        expect(page).to have_selector('.merge-request', count: 2)
-      end
+      expect_mr_list_count(2)
 
       click_button 'Last created'
       page.within '.dropdown-menu-sort' do
@@ -352,4 +261,38 @@ describe 'Filter merge requests', feature: true do
       end
     end
   end
+
+  describe 'filter by assignee id', js: true do
+    it 'filter by current user' do
+      visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: user.id)
+
+      expect_filtered_search_input("assignee:@#{user.username}")
+    end
+
+    it 'filter by new user' do
+      new_user = create(:user)
+      project.add_developer(new_user)
+
+      visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: new_user.id)
+
+      expect_filtered_search_input("assignee:@#{new_user.username}")
+    end
+  end
+
+  describe 'filter by author id', js: true do
+    it 'filter by current user' do
+      visit namespace_project_merge_requests_path(project.namespace, project, author_id: user.id)
+
+      expect_filtered_search_input("author:@#{user.username}")
+    end
+
+    it 'filter by new user' do
+      new_user = create(:user)
+      project.add_developer(new_user)
+
+      visit namespace_project_merge_requests_path(project.namespace, project, author_id: new_user.id)
+
+      expect_filtered_search_input("author:@#{new_user.username}")
+    end
+  end
 end
diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb
index 3a7ece7e1d6de16f317b72320c8fba9f5080f3a9..58f11499e3fd47bb1baa688e57b2dae132e14106 100644
--- a/spec/features/merge_requests/reset_filters_spec.rb
+++ b/spec/features/merge_requests/reset_filters_spec.rb
@@ -1,17 +1,20 @@
 require 'rails_helper'
 
 feature 'Issues filter reset button', feature: true, js: true do
+  include FilteredSearchHelpers
+  include MergeRequestHelpers
   include WaitForAjax
   include IssueHelpers
 
-  let!(:project)    { create(:project, :public) }
-  let!(:user)        { create(:user)}
-  let!(:milestone)  { create(:milestone, project: project) }
-  let!(:bug)        { create(:label, project: project, name: 'bug')}
+  let!(:project) { create(:project, :public) }
+  let!(:user) { create(:user) }
+  let!(:milestone) { create(:milestone, project: project) }
+  let!(:bug) { create(:label, project: project, name: 'bug')}
   let!(:mr1) { create(:merge_request, title: "Feature", source_project: project, target_project: project, source_branch: "Feature", milestone: milestone, author: user, assignee: user) }
   let!(:mr2) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "Bugfix1") }
 
-  let(:merge_request_css) { '.merge-request' }  
+  let(:merge_request_css) { '.merge-request' }
+  let(:clear_search_css) { '.filtered-search-input-container .clear-search' }
 
   before do
     mr2.labels << bug
@@ -50,7 +53,7 @@ feature 'Issues filter reset button', feature: true, js: true do
 
   context 'when author filter has been applied' do
     it 'resets the author filter' do
-      visit_merge_requests(project, author_id: user.id)
+      visit_merge_requests(project, author_username: user.username)
       expect(page).to have_css(merge_request_css, count: 1)
 
       reset_filters
@@ -60,7 +63,7 @@ feature 'Issues filter reset button', feature: true, js: true do
 
   context 'when assignee filter has been applied' do
     it 'resets the assignee filter' do
-      visit_merge_requests(project, assignee_id: user.id)
+      visit_merge_requests(project, assignee_username: user.username)
       expect(page).to have_css(merge_request_css, count: 1)
 
       reset_filters
@@ -70,7 +73,7 @@ feature 'Issues filter reset button', feature: true, js: true do
 
   context 'when all filters have been applied' do
     it 'resets all filters' do
-      visit_merge_requests(project, assignee_id: user.id, author_id: user.id, milestone_title: milestone.title, label_name: bug.name, search: 'Bug')
+      visit_merge_requests(project, assignee_username: user.username, author_username: user.username, milestone_title: milestone.title, label_name: bug.name, search: 'Bug')
       expect(page).to have_css(merge_request_css, count: 0)
 
       reset_filters
@@ -82,15 +85,7 @@ feature 'Issues filter reset button', feature: true, js: true do
     it 'the reset link should not be visible' do
       visit_merge_requests(project)
       expect(page).to have_css(merge_request_css, count: 2)
-      expect(page).not_to have_css '.reset_filters'
+      expect(page).not_to have_css(clear_search_css)
     end
   end
-
-  def visit_merge_requests(project, opts = {})
-    visit namespace_project_merge_requests_path project.namespace, project, opts
-  end
-
-  def reset_filters
-    find('.reset-filters').click
-  end
 end
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
index 0fe5a897565dc68648f282d0c00ef0c0e726afac..7da05defa81fd0871786eba6eb87a9aa8600de71 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -186,7 +186,7 @@ describe "Search", feature: true  do
           sleep 2
 
           expect(page).to have_selector('.merge-requests-holder')
-          expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name)
+          expect(find('.filtered-search').value).to eq("assignee:@#{user.username}")
         end
 
         it 'takes user to her MR page when MR authored is clicked' do
@@ -194,7 +194,7 @@ describe "Search", feature: true  do
           sleep 2
 
           expect(page).to have_selector('.merge-requests-holder')
-          expect(find('.js-author-search .dropdown-toggle-text')).to have_content(user.name)
+          expect(find('.filtered-search').value).to eq("author:@#{user.username}")
         end
       end
 
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index cb8754581c094630908e2a3593c26ab9d2e939a1..aaf058bd7550fe988694aa3e9d4aa1d7f14dec22 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -89,8 +89,8 @@ require('vendor/fuzzaldrin-plus');
     var a1, a2, a3, a4, issuesAssignedToMeLink, issuesIHaveCreatedLink, mrsAssignedToMeLink, mrsIHaveCreatedLink;
     issuesAssignedToMeLink = issuesPath + "/?assignee_username=" + userName;
     issuesIHaveCreatedLink = issuesPath + "/?author_username=" + userName;
-    mrsAssignedToMeLink = mrsPath + "/?assignee_id=" + userId;
-    mrsIHaveCreatedLink = mrsPath + "/?author_id=" + userId;
+    mrsAssignedToMeLink = mrsPath + "/?assignee_username=" + userName;
+    mrsIHaveCreatedLink = mrsPath + "/?author_username=" + userName;
     a1 = "a[href='" + issuesAssignedToMeLink + "']";
     a2 = "a[href='" + issuesIHaveCreatedLink + "']";
     a3 = "a[href='" + mrsAssignedToMeLink + "']";
diff --git a/spec/support/filtered_search_helpers.rb b/spec/support/filtered_search_helpers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..58f6636e680297fde32c00a2331b9af9b906285b
--- /dev/null
+++ b/spec/support/filtered_search_helpers.rb
@@ -0,0 +1,37 @@
+module FilteredSearchHelpers
+  def filtered_search
+    page.find('.filtered-search')
+  end
+
+  def input_filtered_search(search_term, submit: true)
+    filtered_search.set(search_term)
+
+    if submit
+      filtered_search.send_keys(:enter)
+    end
+  end
+
+  def input_filtered_search_keys(search_term)
+    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-input-container .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
+end
diff --git a/spec/support/merge_request_helpers.rb b/spec/support/merge_request_helpers.rb
index d5801c8272f9bda104cfe7542a5d68d5bbddc3d2..326b85eabd01ab5a300c66256e54bf5ac8b0987b 100644
--- a/spec/support/merge_request_helpers.rb
+++ b/spec/support/merge_request_helpers.rb
@@ -10,4 +10,13 @@ module MergeRequestHelpers
   def last_merge_request
     page.all('ul.mr-list > li').last.text
   end
+
+  def expect_mr_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)
+    page.within '.mr-list' do
+      expect(page).to have_selector('.merge-request', count: open_count)
+    end
+  end
 end