diff --git a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
new file mode 100644
index 0000000..414c9f3
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FilterTest.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler;
+
+use Behat\Mink\Element\NodeElement;
+use Drupal\config\Tests\SchemaCheckTestTrait;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the field field handler UI.
+ *
+ * @group views
+ */
+class FilterTest extends JavascriptTestBase {
+  use SchemaCheckTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_ui', 'user'];
+
+  /**
+   * The account.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $account;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Disable automatic live preview to make the sequence of calls clearer.
+    \Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save();
+
+    $this->account = $this->drupalCreateUser(['administer views']);
+    $this->drupalLogin($this->account);
+
+    NodeType::create([
+      'type' => 'page',
+    ])->save();
+
+    FieldConfig::create([
+      'entity_type' => 'node',
+      'field_name' => 'body',
+      'bundle' => 'page',
+    ])->save();
+  }
+
+  /**
+   * Test adding a filter handler.
+   */
+  public function testAddingFilter() {
+    $web_assert = $this->assertSession();
+
+    $url = '/admin/structure/views/view/content';
+    $this->drupalGet($url);
+
+    $session = $this->getSession();
+    $page = $this->getSession()->getPage();
+
+    // Open the 'Add filter dialog'.
+    $page->clickLink('views-add-filter');
+    $web_assert->assertWaitOnAjaxRequest();
+
+    // Test filtering by type.
+    $page->fillField('override[controls][group]', 'content');
+    $session->wait(1000);
+
+    $handler_rows = $page->findAll('css', 'tr.filterable-option');
+    $handler_rows = $this->filterVisibleElements($handler_rows);
+
+    foreach ($handler_rows as $handler_row) {
+      // Test that all the visible rows are of the 'content' type.
+      $this->assertTrue(strpos($handler_row->getAttribute('class'), 'content') !== FALSE);
+    }
+
+    // Search for a specific title and test that this is now the only one shown.
+    $page->fillField('override[controls][options_search]', 'body (body)');
+    $session->wait(1000);
+    $handler_rows = $page->findAll('css', 'tr.filterable-option');
+    $handler_rows = $this->filterVisibleElements($handler_rows);
+    $this->assertCount(1, $handler_rows);
+
+    // Select the body field and apply the choice.
+    $page->checkField('name[node__body.body_value]');
+    $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
+    $add_button->click();
+    $web_assert->assertWaitOnAjaxRequest();
+
+    // Expose the filter.
+    $page->findField('options[expose_button][checkbox][checkbox]')->click();
+    $web_assert->assertWaitOnAjaxRequest();
+    $page->pressButton('Apply');
+    $web_assert->assertWaitOnAjaxRequest();
+    $web_assert->responseContains('Content: body (exposed)');
+  }
+
+  /**
+   * Removes any non-visible elements from the passed array.
+   *
+   * @param NodeElement[] $elements
+   * @return NodeElement[]
+   */
+  protected function filterVisibleElements($elements) {
+    $elements = array_filter($elements, function($element) {
+      return $element->isVisible();
+    });
+    return $elements;
+  }
+}
