diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index d8c5833..22b1221 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -480,3 +480,10 @@ form_test.get_form:
     _form: '\Drupal\form_test\Form\FormTestGetForm'
   requirements:
     _access: 'TRUE'
+
+form_test.javascript_states_form:
+  path: '/form-test/javascript-states-form'
+  defaults:
+    _form: '\Drupal\form_test\Form\JavascriptStatesForm'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
new file mode 100644
index 0000000..8a95739
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\form_test\Form\JavascriptStatesForm.
+ */
+
+namespace Drupal\form_test\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Builds a simple form that redirects on submit.
+ *
+ * @see \Drupal\form_test\Plugin\Block\RedirectFormBlock
+ */
+class JavascriptStatesForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'javascript_states_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    // Hide name field when the anonymous checkbox is checked.
+    $form['name'] = array(
+      '#type' => 'textfield',
+      '#title' => $this->t('Name'),
+      '#states' => array(
+        'invisible' => array(
+          ':input[name="anonymous"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    // Uncheck anonymous field when the name field is filled.
+    $form['anonymous'] = array(
+      '#type' => 'checkbox',
+      '#title' => $this->t('I prefer to remain anonymous'),
+      '#states' => array(
+        'unchecked' => array(
+          ':input[name="name"]' => array('filled' => TRUE),
+        ),
+      ),
+    );
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
new file mode 100644
index 0000000..9d32efc
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\FunctionalJavascriptTests\Core\Form\JavascriptStatesTest.
+ */
+
+namespace Drupal\FunctionalJavascriptTests\Core\Form;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Symfony\Component\CssSelector\CssSelector;
+
+/**
+ * Tests if we can execute JavaScript in the browser.
+ *
+ * @group javascript
+ */
+class JavascriptStatesTest extends JavascriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['form_test'];
+
+  /**
+   * #states
+   */
+  public function testJavascriptStates() {
+    $this->drupalGet('form-test/javascript-states-form');
+    $driver = $this->getSession()->getDriver();
+
+    $this->assertElementNotVisible('#edit-name', 'Name field is not visible.');
+    $xpath = CssSelector::toXPath('#edit-anonymous');
+
+    // This should make the element visible but it does not.
+    $driver->uncheck($xpath);
+    $this->assertElementNotVisible('#edit-name', 'Name field is not visible.');
+
+    // This should make the element visible but it is already.
+    $driver->check($xpath);
+    $this->assertElementNotVisible('#edit-name', 'Name field is not visible.');
+
+    // This should make the element visible and it does!
+    $driver->uncheck($xpath);
+    $this->assertElementVisible('#edit-name', 'Name field is visible.');
+  }
+
+}
