diff --git a/core/COPYRIGHT.txt b/core/COPYRIGHT.txt
index 618e3de..486b2d3 100644
--- a/core/COPYRIGHT.txt
+++ b/core/COPYRIGHT.txt
@@ -20,7 +20,7 @@ Drupal includes works under other copyright notices and distributed
 according to the terms of the GNU General Public License or a compatible
 license, including:
 
-Javascript
+JavaScript
 
   Farbtastic - Copyright (c) 2010 Matt Farina
 
diff --git a/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php b/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
index f42c89c..e3f68f2 100644
--- a/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
+++ b/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
@@ -9,7 +9,7 @@ class BigPipeRegressionTestController {
   const MARKER_2678662 = '<script>var hitsTheFloor = "</body>";</script>';
 
   /**
-   * @see \Drupal\Tests\big_pipe\FunctionalJavascript\BigPipeRegressionTest::testMultipleBodies_2678662()
+   * @see \Drupal\Tests\big_pipe\FunctionalJavaScript\BigPipeRegressionTest::testMultipleBodies_2678662()
    */
   public function regression2678662() {
     return [
diff --git a/core/modules/big_pipe/tests/src/FunctionalJavaScript/BigPipeRegressionTest.php b/core/modules/big_pipe/tests/src/FunctionalJavaScript/BigPipeRegressionTest.php
new file mode 100644
index 0000000..82efddd
--- /dev/null
+++ b/core/modules/big_pipe/tests/src/FunctionalJavaScript/BigPipeRegressionTest.php
@@ -0,0 +1,187 @@
+<?php
+
+namespace Drupal\Tests\big_pipe\FunctionalJavaScript;
+
+use Drupal\big_pipe\Render\BigPipe;
+use Drupal\big_pipe_regression_test\BigPipeRegressionTestController;
+use Drupal\comment\CommentInterface;
+use Drupal\comment\Entity\Comment;
+use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
+use Drupal\comment\Tests\CommentTestTrait;
+use Drupal\Core\Url;
+use Drupal\editor\Entity\Editor;
+use Drupal\filter\Entity\FilterFormat;
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\simpletest\NodeCreationTrait;
+
+/**
+ * BigPipe regression tests.
+ *
+ * @group big_pipe
+ */
+class BigPipeRegressionTest extends JavaScriptTestBase {
+
+  use CommentTestTrait;
+  use ContentTypeCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'big_pipe',
+    'big_pipe_regression_test',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    // Use the big_pipe_test_theme theme.
+    $this->container->get('theme_installer')->install(['big_pipe_test_theme']);
+    $this->container->get('config.factory')->getEditable('system.theme')->set('default', 'big_pipe_test_theme')->save();
+  }
+
+  /**
+   * Ensure comment form works with history and big_pipe modules.
+   *
+   * @see https://www.drupal.org/node/2698811
+   */
+  public function testCommentForm_2698811() {
+    $this->assertTrue($this->container->get('module_installer')->install(['comment', 'history', 'ckeditor'], TRUE), 'Installed modules.');
+
+    // Ensure an `article` node type exists.
+    $this->createContentType(['type' => 'article']);
+    $this->addDefaultCommentField('node', 'article');
+
+    // Enable CKEditor.
+    $format = $this->randomMachineName();
+    FilterFormat::create([
+      'format' => $format,
+      'name' => $this->randomString(),
+      'weight' => 1,
+      'filters' => [],
+    ])->save();
+    $settings['toolbar']['rows'] = [
+      [
+        [
+          'name' => 'Links',
+          'items' => [
+            'DrupalLink',
+            'DrupalUnlink',
+          ],
+        ],
+      ],
+    ];
+    $editor = Editor::create([
+      'format' => $format,
+      'editor' => 'ckeditor',
+    ]);
+    $editor->setSettings($settings);
+    $editor->save();
+
+    $admin_user = $this->drupalCreateUser([
+      'access comments',
+      'post comments',
+      'use text format ' . $format,
+    ]);
+    $this->drupalLogin($admin_user);
+
+    $node = $this->createNode([
+      'type' => 'article',
+      'comment' => CommentItemInterface::OPEN,
+    ]);
+    // Create some comments.
+    foreach (range(1, 5) as $i) {
+      $comment = Comment::create([
+        'status' => CommentInterface::PUBLISHED,
+        'field_name' => 'comment',
+        'entity_type' => 'node',
+        'entity_id' => $node->id(),
+      ]);
+      $comment->save();
+    }
+    $this->drupalGet($node->toUrl()->toString());
+    // Confirm that CKEditor loaded.
+    $javascript = <<<JS
+    (function(){
+      return Object.keys(CKEDITOR.instances).length > 0;
+    }());
+JS;
+    $this->assertJsCondition($javascript);
+  }
+
+  /**
+   * Ensure BigPipe works despite inline JS containing the string "</body>".
+   *
+   * @see https://www.drupal.org/node/2678662
+   */
+  public function testMultipleClosingBodies_2678662() {
+    $this->assertTrue($this->container->get('module_installer')->install(['render_placeholder_message_test'], TRUE), 'Installed modules.');
+
+    $this->drupalLogin($this->drupalCreateUser());
+    $this->drupalGet(Url::fromRoute('big_pipe_regression_test.2678662'));
+
+    // Confirm that AJAX behaviors were instantiated, if not, this points to a
+    // JavaScript syntax error.
+    $javascript = <<<JS
+    (function(){
+      return Object.keys(Drupal.ajax.instances).length > 0;
+    }());
+JS;
+    $this->assertJsCondition($javascript);
+
+    // Besides verifying there is no JavaScript syntax error, also verify the
+    // HTML structure.
+    $this->assertSession()
+      ->responseContains(BigPipe::STOP_SIGNAL . "\n\n\n</body></html>", 'The BigPipe stop signal is present just before the closing </body> and </html> tags.');
+    $js_code_until_closing_body_tag = substr(BigPipeRegressionTestController::MARKER_2678662, 0, strpos(BigPipeRegressionTestController::MARKER_2678662, '</body>'));
+    $this->assertSession()
+      ->responseNotContains($js_code_until_closing_body_tag . "\n" . BigPipe::START_SIGNAL, 'The BigPipe start signal does NOT start at the closing </body> tag string in an inline script.');
+  }
+
+  /**
+   * Ensure messages set in placeholders always appear.
+   *
+   * @see https://www.drupal.org/node/2712935
+   */
+  public function testMessages_2712935() {
+    $this->assertTrue($this->container->get('module_installer')->install(['render_placeholder_message_test'], TRUE), 'Installed modules.');
+
+    $this->drupalLogin($this->drupalCreateUser());
+    $messages_markup = '<div role="contentinfo" aria-label="Status message"';
+
+    $test_routes = [
+      // Messages placeholder rendered first.
+      'render_placeholder_message_test.first',
+      // Messages placeholder rendered after one, before another.
+      'render_placeholder_message_test.middle',
+      // Messages placeholder rendered last.
+      'render_placeholder_message_test.last',
+    ];
+
+    $assert = $this->assertSession();
+    foreach ($test_routes as $route) {
+      // Verify that we start off with zero messages queued.
+      $this->drupalGet(Url::fromRoute('render_placeholder_message_test.queued'));
+      $assert->responseNotContains($messages_markup);
+
+      // Verify the test case at this route behaves as expected.
+      $this->drupalGet(Url::fromRoute($route));
+      $assert->elementContains('css', 'p.logged-message:nth-of-type(1)', 'Message: P1');
+      $assert->elementContains('css', 'p.logged-message:nth-of-type(2)', 'Message: P2');
+      $assert->responseContains($messages_markup);
+      $assert->elementExists('css', 'div[aria-label="Status message"] ul');
+      $assert->elementContains('css', 'div[aria-label="Status message"] ul li:nth-of-type(1)', 'P1');
+      $assert->elementContains('css', 'div[aria-label="Status message"] ul li:nth-of-type(2)', 'P2');
+
+      // Verify that we end with all messages printed, hence again zero queued.
+      $this->drupalGet(Url::fromRoute('render_placeholder_message_test.queued'));
+      $assert->responseNotContains($messages_markup);
+    }
+  }
+
+}
diff --git a/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php b/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php
deleted file mode 100644
index a99d5fc..0000000
--- a/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php
+++ /dev/null
@@ -1,187 +0,0 @@
-<?php
-
-namespace Drupal\Tests\big_pipe\FunctionalJavascript;
-
-use Drupal\big_pipe\Render\BigPipe;
-use Drupal\big_pipe_regression_test\BigPipeRegressionTestController;
-use Drupal\comment\CommentInterface;
-use Drupal\comment\Entity\Comment;
-use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
-use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\Core\Url;
-use Drupal\editor\Entity\Editor;
-use Drupal\filter\Entity\FilterFormat;
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\simpletest\ContentTypeCreationTrait;
-use Drupal\simpletest\NodeCreationTrait;
-
-/**
- * BigPipe regression tests.
- *
- * @group big_pipe
- */
-class BigPipeRegressionTest extends JavascriptTestBase {
-
-  use CommentTestTrait;
-  use ContentTypeCreationTrait;
-  use NodeCreationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = [
-    'big_pipe',
-    'big_pipe_regression_test',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    parent::setUp();
-
-    // Use the big_pipe_test_theme theme.
-    $this->container->get('theme_installer')->install(['big_pipe_test_theme']);
-    $this->container->get('config.factory')->getEditable('system.theme')->set('default', 'big_pipe_test_theme')->save();
-  }
-
-  /**
-   * Ensure comment form works with history and big_pipe modules.
-   *
-   * @see https://www.drupal.org/node/2698811
-   */
-  public function testCommentForm_2698811() {
-    $this->assertTrue($this->container->get('module_installer')->install(['comment', 'history', 'ckeditor'], TRUE), 'Installed modules.');
-
-    // Ensure an `article` node type exists.
-    $this->createContentType(['type' => 'article']);
-    $this->addDefaultCommentField('node', 'article');
-
-    // Enable CKEditor.
-    $format = $this->randomMachineName();
-    FilterFormat::create([
-      'format' => $format,
-      'name' => $this->randomString(),
-      'weight' => 1,
-      'filters' => [],
-    ])->save();
-    $settings['toolbar']['rows'] = [
-      [
-        [
-          'name' => 'Links',
-          'items' => [
-            'DrupalLink',
-            'DrupalUnlink',
-          ],
-        ],
-      ],
-    ];
-    $editor = Editor::create([
-      'format' => $format,
-      'editor' => 'ckeditor',
-    ]);
-    $editor->setSettings($settings);
-    $editor->save();
-
-    $admin_user = $this->drupalCreateUser([
-      'access comments',
-      'post comments',
-      'use text format ' . $format,
-    ]);
-    $this->drupalLogin($admin_user);
-
-    $node = $this->createNode([
-      'type' => 'article',
-      'comment' => CommentItemInterface::OPEN,
-    ]);
-    // Create some comments.
-    foreach (range(1, 5) as $i) {
-      $comment = Comment::create([
-        'status' => CommentInterface::PUBLISHED,
-        'field_name' => 'comment',
-        'entity_type' => 'node',
-        'entity_id' => $node->id(),
-      ]);
-      $comment->save();
-    }
-    $this->drupalGet($node->toUrl()->toString());
-    // Confirm that CKEditor loaded.
-    $javascript = <<<JS
-    (function(){
-      return Object.keys(CKEDITOR.instances).length > 0;
-    }());
-JS;
-    $this->assertJsCondition($javascript);
-  }
-
-  /**
-   * Ensure BigPipe works despite inline JS containing the string "</body>".
-   *
-   * @see https://www.drupal.org/node/2678662
-   */
-  public function testMultipleClosingBodies_2678662() {
-    $this->assertTrue($this->container->get('module_installer')->install(['render_placeholder_message_test'], TRUE), 'Installed modules.');
-
-    $this->drupalLogin($this->drupalCreateUser());
-    $this->drupalGet(Url::fromRoute('big_pipe_regression_test.2678662'));
-
-    // Confirm that AJAX behaviors were instantiated, if not, this points to a
-    // JavaScript syntax error.
-    $javascript = <<<JS
-    (function(){
-      return Object.keys(Drupal.ajax.instances).length > 0;
-    }());
-JS;
-    $this->assertJsCondition($javascript);
-
-    // Besides verifying there is no JavaScript syntax error, also verify the
-    // HTML structure.
-    $this->assertSession()
-      ->responseContains(BigPipe::STOP_SIGNAL . "\n\n\n</body></html>", 'The BigPipe stop signal is present just before the closing </body> and </html> tags.');
-    $js_code_until_closing_body_tag = substr(BigPipeRegressionTestController::MARKER_2678662, 0, strpos(BigPipeRegressionTestController::MARKER_2678662, '</body>'));
-    $this->assertSession()
-      ->responseNotContains($js_code_until_closing_body_tag . "\n" . BigPipe::START_SIGNAL, 'The BigPipe start signal does NOT start at the closing </body> tag string in an inline script.');
-  }
-
-  /**
-   * Ensure messages set in placeholders always appear.
-   *
-   * @see https://www.drupal.org/node/2712935
-   */
-  public function testMessages_2712935() {
-    $this->assertTrue($this->container->get('module_installer')->install(['render_placeholder_message_test'], TRUE), 'Installed modules.');
-
-    $this->drupalLogin($this->drupalCreateUser());
-    $messages_markup = '<div role="contentinfo" aria-label="Status message"';
-
-    $test_routes = [
-      // Messages placeholder rendered first.
-      'render_placeholder_message_test.first',
-      // Messages placeholder rendered after one, before another.
-      'render_placeholder_message_test.middle',
-      // Messages placeholder rendered last.
-      'render_placeholder_message_test.last',
-    ];
-
-    $assert = $this->assertSession();
-    foreach ($test_routes as $route) {
-      // Verify that we start off with zero messages queued.
-      $this->drupalGet(Url::fromRoute('render_placeholder_message_test.queued'));
-      $assert->responseNotContains($messages_markup);
-
-      // Verify the test case at this route behaves as expected.
-      $this->drupalGet(Url::fromRoute($route));
-      $assert->elementContains('css', 'p.logged-message:nth-of-type(1)', 'Message: P1');
-      $assert->elementContains('css', 'p.logged-message:nth-of-type(2)', 'Message: P2');
-      $assert->responseContains($messages_markup);
-      $assert->elementExists('css', 'div[aria-label="Status message"] ul');
-      $assert->elementContains('css', 'div[aria-label="Status message"] ul li:nth-of-type(1)', 'P1');
-      $assert->elementContains('css', 'div[aria-label="Status message"] ul li:nth-of-type(2)', 'P2');
-
-      // Verify that we end with all messages printed, hence again zero queued.
-      $this->drupalGet(Url::fromRoute('render_placeholder_message_test.queued'));
-      $assert->responseNotContains($messages_markup);
-    }
-  }
-
-}
diff --git a/core/modules/big_pipe/tests/themes/big_pipe_test_theme/templates/field--comment.html.twig b/core/modules/big_pipe/tests/themes/big_pipe_test_theme/templates/field--comment.html.twig
index a26fa78..518d4f7 100644
--- a/core/modules/big_pipe/tests/themes/big_pipe_test_theme/templates/field--comment.html.twig
+++ b/core/modules/big_pipe/tests/themes/big_pipe_test_theme/templates/field--comment.html.twig
@@ -3,7 +3,7 @@
  * @file
  * Test that comments still work with the form above instead of below.
  *
- * @see \Drupal\Tests\big_pipe\FunctionalJavascript\BigPipeRegressionTest::testCommentForm_2698811()
+ * @see \Drupal\Tests\big_pipe\FunctionalJavaScript\BigPipeRegressionTest::testCommentForm_2698811()
  */
 #}
 <section{{ attributes }}>
diff --git a/core/modules/block_content/js/block_content.js b/core/modules/block_content/js/block_content.js
index bbc0533..a30b73b 100644
--- a/core/modules/block_content/js/block_content.js
+++ b/core/modules/block_content/js/block_content.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Defines Javascript behaviors for the block_content module.
+ * Defines JavaScript behaviors for the block_content module.
  */
 
 (function ($, Drupal) {
diff --git a/core/modules/book/book.js b/core/modules/book/book.js
index 2cc7881..dc4ff2c 100644
--- a/core/modules/book/book.js
+++ b/core/modules/book/book.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Javascript behaviors for the Book module.
+ * JavaScript behaviors for the Book module.
  */
 
 (function ($, Drupal) {
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index ecccb74..1123abf 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -147,7 +147,7 @@ function book_form_node_form_alter(&$form, FormStateInterface $form_state, $form
   if ($access) {
     $collapsed = !($node->isNew() && !empty($node->book['pid']));
     $form = \Drupal::service('book.manager')->addFormElements($form, $form_state, $node, $account, $collapsed);
-    // The "js-hide" class hides submit button when Javascript is enabled.
+    // The "js-hide" class hides submit button when JavaScript is enabled.
     $form['book']['pick-book'] = array(
       '#type' => 'submit',
       '#value' => t('Change book (update list of parents)'),
diff --git a/core/modules/content_translation/src/FieldTranslationSynchronizer.php b/core/modules/content_translation/src/FieldTranslationSynchronizer.php
index 8f7584d..0b6d41f 100644
--- a/core/modules/content_translation/src/FieldTranslationSynchronizer.php
+++ b/core/modules/content_translation/src/FieldTranslationSynchronizer.php
@@ -64,7 +64,7 @@ public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode
 
         // If a group was selected has the require_all_groups_for_translation
         // flag set, there are no untranslatable columns. This is done because
-        // the UI adds Javascript that disables the other checkboxes, so their
+        // the UI adds JavaScript that disables the other checkboxes, so their
         // values are not saved.
         foreach (array_filter($translation_sync) as $group) {
           if (!empty($column_groups[$group]['require_all_groups_for_translation'])) {
diff --git a/core/modules/locale/src/Tests/LocaleJavaScriptTranslationTest.php b/core/modules/locale/src/Tests/LocaleJavaScriptTranslationTest.php
new file mode 100644
index 0000000..f6a4596
--- /dev/null
+++ b/core/modules/locale/src/Tests/LocaleJavaScriptTranslationTest.php
@@ -0,0 +1,145 @@
+<?php
+
+namespace Drupal\locale\Tests;
+
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\simpletest\WebTestBase;
+use Drupal\Component\Utility\SafeMarkup;
+
+/**
+ * Tests parsing js files for translatable strings.
+ *
+ * @group locale
+ */
+class LocaleJavaScriptTranslationTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('locale', 'locale_test');
+
+  public function testFileParsing() {
+    $filename = __DIR__ . '/../../tests/locale_test.js';
+
+    // Parse the file to look for source strings.
+    _locale_parse_js_file($filename);
+
+    // Get all of the source strings that were found.
+    $strings = $this->container
+      ->get('locale.storage')
+      ->getStrings(array(
+        'type' => 'javascript',
+        'name' => $filename,
+      ));
+
+    $source_strings = array();
+    foreach ($strings as $string) {
+      $source_strings[$string->source] = $string->context;
+    }
+
+    $etx = LOCALE_PLURAL_DELIMITER;
+    // List of all strings that should be in the file.
+    $test_strings = array(
+      'Standard Call t' => '',
+      'Whitespace Call t' => '',
+
+      'Single Quote t' => '',
+      "Single Quote \\'Escaped\\' t" => '',
+      'Single Quote Concat strings t' => '',
+
+      'Double Quote t' => '',
+      "Double Quote \\\"Escaped\\\" t" => '',
+      'Double Quote Concat strings t' => '',
+
+      'Context !key Args t' => 'Context string',
+
+      'Context Unquoted t' => 'Context string unquoted',
+      'Context Single Quoted t' => 'Context string single quoted',
+      'Context Double Quoted t' => 'Context string double quoted',
+
+      "Standard Call plural{$etx}Standard Call @count plural" => '',
+      "Whitespace Call plural{$etx}Whitespace Call @count plural" => '',
+
+      "Single Quote plural{$etx}Single Quote @count plural" => '',
+      "Single Quote \\'Escaped\\' plural{$etx}Single Quote \\'Escaped\\' @count plural" => '',
+
+      "Double Quote plural{$etx}Double Quote @count plural" => '',
+      "Double Quote \\\"Escaped\\\" plural{$etx}Double Quote \\\"Escaped\\\" @count plural" => '',
+
+      "Context !key Args plural{$etx}Context !key Args @count plural" => 'Context string',
+
+      "Context Unquoted plural{$etx}Context Unquoted @count plural" => 'Context string unquoted',
+      "Context Single Quoted plural{$etx}Context Single Quoted @count plural" => 'Context string single quoted',
+      "Context Double Quoted plural{$etx}Context Double Quoted @count plural" => 'Context string double quoted',
+    );
+
+    // Assert that all strings were found properly.
+    foreach ($test_strings as $str => $context) {
+      $args = array('%source' => $str, '%context' => $context);
+
+      // Make sure that the string was found in the file.
+      $this->assertTrue(isset($source_strings[$str]), SafeMarkup::format('Found source string: %source', $args));
+
+      // Make sure that the proper context was matched.
+      $message = $context ? SafeMarkup::format('Context for %source is %context', $args) : SafeMarkup::format('Context for %source is blank', $args);
+      $this->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, $message);
+    }
+
+    $this->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');
+  }
+
+  /**
+   * Assert translations JS is added before drupal.js, because it depends on it.
+   */
+  public function testLocaleTranslationJsDependencies() {
+    // User to add and remove language.
+    $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'translate interface'));
+
+    // Add custom language.
+    $this->drupalLogin($admin_user);
+    // Code for the language.
+    $langcode = 'es';
+    // The English name for the language.
+    $name = $this->randomMachineName(16);
+    // The domain prefix.
+    $prefix = $langcode;
+    $edit = array(
+      'predefined_langcode' => 'custom',
+      'langcode' => $langcode,
+      'label' => $name,
+      'direction' => LanguageInterface::DIRECTION_LTR,
+    );
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
+
+    // Set path prefix.
+    $edit = array("prefix[$langcode]" => $prefix);
+    $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
+
+    // This forces locale.admin.js string sources to be imported, which contains
+    // the next translation.
+    $this->drupalGet($prefix . '/admin/config/regional/translate');
+
+    // Translate a string in locale.admin.js to our new language.
+    $strings = \Drupal::service('locale.storage')
+      ->getStrings(array(
+        'source' => 'Show description',
+        'type' => 'javascript',
+        'name' => 'core/modules/locale/locale.admin.js',
+      ));
+    $string = $strings[0];
+
+    $this->drupalPostForm(NULL, ['string' => 'Show description'], t('Filter'));
+    $edit = ['strings[' . $string->lid . '][translations][0]' => $this->randomString(16)];
+    $this->drupalPostForm(NULL, $edit, t('Save translations'));
+
+    // Calculate the filename of the JS including the translations.
+    $js_translation_files = \Drupal::state()->get('locale.translation.javascript');
+    $js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js';
+
+    // Assert translations JS is included before drupal.js.
+    $this->assertTrue(strpos($this->content, $js_filename) < strpos($this->content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
+  }
+
+}
diff --git a/core/modules/locale/src/Tests/LocaleJavascriptTranslationTest.php b/core/modules/locale/src/Tests/LocaleJavascriptTranslationTest.php
deleted file mode 100644
index b16ba18..0000000
--- a/core/modules/locale/src/Tests/LocaleJavascriptTranslationTest.php
+++ /dev/null
@@ -1,145 +0,0 @@
-<?php
-
-namespace Drupal\locale\Tests;
-
-use Drupal\Core\Language\LanguageInterface;
-use Drupal\simpletest\WebTestBase;
-use Drupal\Component\Utility\SafeMarkup;
-
-/**
- * Tests parsing js files for translatable strings.
- *
- * @group locale
- */
-class LocaleJavascriptTranslationTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('locale', 'locale_test');
-
-  public function testFileParsing() {
-    $filename = __DIR__ . '/../../tests/locale_test.js';
-
-    // Parse the file to look for source strings.
-    _locale_parse_js_file($filename);
-
-    // Get all of the source strings that were found.
-    $strings = $this->container
-      ->get('locale.storage')
-      ->getStrings(array(
-        'type' => 'javascript',
-        'name' => $filename,
-      ));
-
-    $source_strings = array();
-    foreach ($strings as $string) {
-      $source_strings[$string->source] = $string->context;
-    }
-
-    $etx = LOCALE_PLURAL_DELIMITER;
-    // List of all strings that should be in the file.
-    $test_strings = array(
-      'Standard Call t' => '',
-      'Whitespace Call t' => '',
-
-      'Single Quote t' => '',
-      "Single Quote \\'Escaped\\' t" => '',
-      'Single Quote Concat strings t' => '',
-
-      'Double Quote t' => '',
-      "Double Quote \\\"Escaped\\\" t" => '',
-      'Double Quote Concat strings t' => '',
-
-      'Context !key Args t' => 'Context string',
-
-      'Context Unquoted t' => 'Context string unquoted',
-      'Context Single Quoted t' => 'Context string single quoted',
-      'Context Double Quoted t' => 'Context string double quoted',
-
-      "Standard Call plural{$etx}Standard Call @count plural" => '',
-      "Whitespace Call plural{$etx}Whitespace Call @count plural" => '',
-
-      "Single Quote plural{$etx}Single Quote @count plural" => '',
-      "Single Quote \\'Escaped\\' plural{$etx}Single Quote \\'Escaped\\' @count plural" => '',
-
-      "Double Quote plural{$etx}Double Quote @count plural" => '',
-      "Double Quote \\\"Escaped\\\" plural{$etx}Double Quote \\\"Escaped\\\" @count plural" => '',
-
-      "Context !key Args plural{$etx}Context !key Args @count plural" => 'Context string',
-
-      "Context Unquoted plural{$etx}Context Unquoted @count plural" => 'Context string unquoted',
-      "Context Single Quoted plural{$etx}Context Single Quoted @count plural" => 'Context string single quoted',
-      "Context Double Quoted plural{$etx}Context Double Quoted @count plural" => 'Context string double quoted',
-    );
-
-    // Assert that all strings were found properly.
-    foreach ($test_strings as $str => $context) {
-      $args = array('%source' => $str, '%context' => $context);
-
-      // Make sure that the string was found in the file.
-      $this->assertTrue(isset($source_strings[$str]), SafeMarkup::format('Found source string: %source', $args));
-
-      // Make sure that the proper context was matched.
-      $message = $context ? SafeMarkup::format('Context for %source is %context', $args) : SafeMarkup::format('Context for %source is blank', $args);
-      $this->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, $message);
-    }
-
-    $this->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');
-  }
-
-  /**
-   * Assert translations JS is added before drupal.js, because it depends on it.
-   */
-  public function testLocaleTranslationJsDependencies() {
-    // User to add and remove language.
-    $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'translate interface'));
-
-    // Add custom language.
-    $this->drupalLogin($admin_user);
-    // Code for the language.
-    $langcode = 'es';
-    // The English name for the language.
-    $name = $this->randomMachineName(16);
-    // The domain prefix.
-    $prefix = $langcode;
-    $edit = array(
-      'predefined_langcode' => 'custom',
-      'langcode' => $langcode,
-      'label' => $name,
-      'direction' => LanguageInterface::DIRECTION_LTR,
-    );
-    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
-
-    // Set path prefix.
-    $edit = array("prefix[$langcode]" => $prefix);
-    $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
-
-    // This forces locale.admin.js string sources to be imported, which contains
-    // the next translation.
-    $this->drupalGet($prefix . '/admin/config/regional/translate');
-
-    // Translate a string in locale.admin.js to our new language.
-    $strings = \Drupal::service('locale.storage')
-      ->getStrings(array(
-        'source' => 'Show description',
-        'type' => 'javascript',
-        'name' => 'core/modules/locale/locale.admin.js',
-      ));
-    $string = $strings[0];
-
-    $this->drupalPostForm(NULL, ['string' => 'Show description'], t('Filter'));
-    $edit = ['strings[' . $string->lid . '][translations][0]' => $this->randomString(16)];
-    $this->drupalPostForm(NULL, $edit, t('Save translations'));
-
-    // Calculate the filename of the JS including the translations.
-    $js_translation_files = \Drupal::state()->get('locale.translation.javascript');
-    $js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js';
-
-    // Assert translations JS is included before drupal.js.
-    $this->assertTrue(strpos($this->content, $js_filename) < strpos($this->content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
-  }
-
-}
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index aacbc2b..0e3d38c 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -33272,7 +33272,7 @@
   'weight' => '0',
 ))
 ->values(array(
-  'name' => 'LocaleJavascriptTranslationTest',
+  'name' => 'LocaleJavaScriptTranslationTest',
   'type' => 'class',
   'filename' => 'modules/locale/locale.test',
   'module' => 'locale',
diff --git a/core/modules/node/content_types.js b/core/modules/node/content_types.js
index eed93f0..53462cb 100644
--- a/core/modules/node/content_types.js
+++ b/core/modules/node/content_types.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Javascript for the node content editing form.
+ * JavaScript for the node content editing form.
  */
 
 (function ($, Drupal) {
diff --git a/core/modules/node/node.js b/core/modules/node/node.js
index 98af6fd..f1bb06a 100644
--- a/core/modules/node/node.js
+++ b/core/modules/node/node.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Defines Javascript behaviors for the node module.
+ * Defines JavaScript behaviors for the node module.
  */
 
 (function ($, Drupal, drupalSettings) {
diff --git a/core/modules/outside_in/outside_in.module b/core/modules/outside_in/outside_in.module
index 298b994..d72dc32 100644
--- a/core/modules/outside_in/outside_in.module
+++ b/core/modules/outside_in/outside_in.module
@@ -93,7 +93,7 @@ function outside_in_preprocess_block(&$variables) {
   // The main system block does not contain the block contextual links.
   $variables['#cache']['contexts'][] = 'outside_in_is_applied';
   if ($variables['plugin_id'] !== 'system_main_block' && \Drupal::service('outside_in.manager')->isApplicable()) {
-    // Add class and attributes to all blocks to allow Javascript to target.
+    // Add class and attributes to all blocks to allow JavaScript to target.
     $variables['attributes']['class'][] = 'outside-in-editable';
     $variables['attributes']['data-drupal-outsidein'] = 'editable';
   }
diff --git a/core/modules/outside_in/tests/src/FunctionalJavaScript/OffCanvasTest.php b/core/modules/outside_in/tests/src/FunctionalJavaScript/OffCanvasTest.php
new file mode 100644
index 0000000..2d00d26
--- /dev/null
+++ b/core/modules/outside_in/tests/src/FunctionalJavaScript/OffCanvasTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Drupal\Tests\outside_in\FunctionalJavaScript;
+
+/**
+ * Tests the off-canvas tray functionality.
+ *
+ * @group outside_in
+ */
+class OffCanvasTest extends OutsideInJavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['block', 'system', 'toolbar', 'outside_in', 'offcanvas_test'];
+
+  /**
+   * Tests that regular non-contextual links will work with the off-canvas tray.
+   */
+  public function testOffCanvasLinks() {
+    $themes = ['bartik', 'stark'];
+    // Test the same functionality on multiple themes.
+    foreach ($themes as $theme) {
+      $this->enableTheme($theme);
+      $this->drupalGet('/offcanvas-test-links');
+
+      $page = $this->getSession()->getPage();
+      $web_assert = $this->assertSession();
+
+      // Make sure off-canvas tray is on page when first loaded.
+      $web_assert->elementNotExists('css', '#drupal-offcanvas');
+
+      // Check opening and closing with two separate links.
+      // Make sure tray updates to new content.
+      // Check the first link again to make sure the empty title class is
+      // removed.
+      foreach (['1', '2', '1'] as $link_index) {
+        // Click the first test like that should open the page.
+        $page->clickLink("Click Me $link_index!");
+        $this->waitForOffCanvasToOpen();
+
+        // Check that the canvas is not on the page.
+        $web_assert->elementExists('css', '#drupal-offcanvas');
+        // Check that response text is on page.
+        $web_assert->pageTextContains("Thing $link_index says hello");
+        $offcanvas_tray = $this->getTray();
+
+        // Check that tray is visible.
+        $this->assertEquals(TRUE, $offcanvas_tray->isVisible());
+        $header_text = $offcanvas_tray->find('css', '.ui-dialog-title')->getText();
+
+        $tray_text = $offcanvas_tray->findById('drupal-offcanvas')->getText();
+        $this->assertEquals("Thing $link_index says hello", $tray_text);
+
+        // Check no title behavior.
+        if ($link_index == '2') {
+          $web_assert->elementExists('css', '.ui-dialog-empty-title');
+          $this->assertEquals('', $header_text);
+        }
+        else {
+          // Check that header is correct.
+          $this->assertEquals("Thing $link_index", $header_text);
+          $web_assert->elementNotExists('css', '.ui-dialog-empty-title');
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/outside_in/tests/src/FunctionalJavaScript/OutsideInBlockFormTest.php b/core/modules/outside_in/tests/src/FunctionalJavaScript/OutsideInBlockFormTest.php
new file mode 100644
index 0000000..51a88d8
--- /dev/null
+++ b/core/modules/outside_in/tests/src/FunctionalJavaScript/OutsideInBlockFormTest.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Drupal\Tests\outside_in\FunctionalJavaScript;
+
+/**
+ * Testing opening and saving block forms in the off-canvas tray.
+ *
+ * @group outside_in
+ */
+class OutsideInBlockFormTest extends OutsideInJavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'node',
+    'block',
+    'system',
+    'breakpoint',
+    'toolbar',
+    'contextual',
+    'outside_in',
+    'quickedit',
+    'search',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    // @todo Ensure that this test class works against bartik and stark:
+    //   https://www.drupal.org/node/2784881.
+    $this->enableTheme('bartik');
+    $user = $this->createUser([
+      'administer blocks',
+      'access contextual links',
+      'access toolbar',
+      'administer nodes',
+      'access in-place editing',
+      'search content',
+    ]);
+    $this->drupalLogin($user);
+
+    $this->placeBlock('system_powered_by_block', ['id' => 'powered']);
+    $this->placeBlock('system_branding_block', ['id' => 'branding']);
+    $this->placeBlock('search_form_block', ['id' => 'search']);
+  }
+
+  /**
+   * Tests opening Offcanvas tray by click blocks and elements in the blocks.
+   */
+  public function testBlocks() {
+    $blocks = [
+      [
+        'id' => 'block-powered',
+        'new_page_text' => 'Can you imagine anyone showing the label on this block?',
+        'element_selector' => '.content a',
+        'button_text' => 'Save Powered by Drupal',
+      ],
+      [
+        'id' => 'block-branding',
+        'new_page_text' => 'The site that will live a very short life.',
+        'element_selector' => 'a[rel="home"]:nth-child(2)',
+        'button_text' => 'Save Site branding',
+      ],
+      [
+        'id' => 'block-search',
+        'element_selector' => '#edit-submit',
+        'button_text' => 'Save Search form',
+      ],
+    ];
+    $page = $this->getSession()->getPage();
+    foreach ($blocks as $block) {
+      $block_selector = '#' . $block['id'];
+      $this->drupalGet('user');
+      $this->toggleEditingMode();
+      $this->openBlockForm($block_selector);
+
+      switch ($block['id']) {
+        case 'block-powered':
+          // Fill out form, save the form.
+          $page->fillField('settings[label]', $block['new_page_text']);
+          $page->checkField('settings[label_display]');
+          break;
+
+        case 'block-branding':
+          // Fill out form, save the form.
+          $page->fillField('settings[site_information][site_name]', $block['new_page_text']);
+          break;
+      }
+
+      if (isset($block['new_page_text'])) {
+        $page->pressButton($block['button_text']);
+        // Make sure the changes are present.
+        $this->getSession()->wait(500);
+        $web_assert = $this->assertSession();
+        $web_assert->pageTextContains($block['new_page_text']);
+      }
+
+      $this->openBlockForm($block_selector);
+
+      $this->toggleEditingMode();
+      // Canvas should close when editing module is closed.
+      $this->waitForOffCanvasToClose();
+
+      // Go into Edit mode again.
+      $this->toggleEditingMode();
+
+      $element_selector = "$block_selector {$block['element_selector']}";
+      // Open block form by clicking a element inside the block.
+      // This confirms that default action for links and form elements is
+      // suppressed.
+      $this->openBlockForm($element_selector);
+
+      // Exit edit mode.
+      $this->toggleEditingMode();
+    }
+  }
+
+  /**
+   * Enables Editing mode by pressing "Edit" button in the toolbar.
+   */
+  protected function toggleEditingMode() {
+    $this->waitForElement('div[data-contextual-id="block:block=powered:langcode=en|outside_in::langcode=en"] .contextual-links a');
+
+    $this->waitForElement('#toolbar-bar', 3000);
+
+    $edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button');
+
+    $edit_button->press();
+  }
+
+  /**
+   * Asserts that Off-Canvas block form is valid.
+   */
+  protected function assertOffCanvasBlockFormIsValid() {
+    $web_assert = $this->assertSession();
+    // Check that common block form elements exist.
+    $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label"]');
+    $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label-display"]');
+    // Check that advanced block form elements do not exist.
+    $web_assert->elementNotExists('css', 'input[data-drupal-selector="edit-visibility-request-path-pages"]');
+    $web_assert->elementNotExists('css', 'select[data-drupal-selector="edit-region"]');
+  }
+
+  /**
+   * Open block form by clicking the element found with a css selector.
+   *
+   * @param string $block_selector
+   *   A css selector selects the block or an element within it.
+   */
+  protected function openBlockForm($block_selector) {
+    $this->click($block_selector);
+    $this->waitForOffCanvasToOpen();
+    $this->assertOffCanvasBlockFormIsValid();
+  }
+}
diff --git a/core/modules/outside_in/tests/src/FunctionalJavaScript/OutsideInJavaScriptTestBase.php b/core/modules/outside_in/tests/src/FunctionalJavaScript/OutsideInJavaScriptTestBase.php
new file mode 100644
index 0000000..cad6c12
--- /dev/null
+++ b/core/modules/outside_in/tests/src/FunctionalJavaScript/OutsideInJavaScriptTestBase.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\Tests\outside_in\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Base class contains common test functionality for the Settings Tray module.
+ */
+abstract class OutsideInJavaScriptTestBase extends JavaScriptTestBase {
+
+  /**
+   * Enables a theme.
+   *
+   * @param string $theme
+   *   The theme.
+   */
+  public function enableTheme($theme) {
+    // Enable the theme.
+    \Drupal::service('theme_installer')->install([$theme]);
+    $theme_config = \Drupal::configFactory()->getEditable('system.theme');
+    $theme_config->set('default', $theme);
+    $theme_config->save();
+  }
+
+  /**
+   * Waits for Off-canvas tray to open.
+   */
+  protected function waitForOffCanvasToOpen() {
+    $web_assert = $this->assertSession();
+    $web_assert->assertWaitOnAjaxRequest();
+    $this->waitForElement('#drupal-offcanvas');
+  }
+
+  /**
+   * Waits for Off-canvas tray to close.
+   */
+  protected function waitForOffCanvasToClose() {
+    $condition = "(jQuery('#drupal-offcanvas').length == 0)";
+    $this->assertJsCondition($condition);
+  }
+
+  /**
+   * Waits for an element to appear on the page.
+   *
+   * @param string $selector
+   *   CSS selector.
+   * @param int $timeout
+   *   (optional) Timeout in milliseconds, defaults to 1000.
+   */
+  protected function waitForElement($selector, $timeout = 1000) {
+    $condition = "(jQuery('$selector').length > 0)";
+    $this->assertJsCondition($condition, $timeout);
+  }
+
+  /**
+   * Gets the Off-Canvas tray element.
+   *
+   * @return \Behat\Mink\Element\NodeElement|null
+   */
+  protected function getTray() {
+    $tray = $this->getSession()->getPage()->find('css', '.ui-dialog[aria-describedby="drupal-offcanvas"]');
+    $this->assertEquals(FALSE, empty($tray), 'The tray was found.');
+    return $tray;
+  }
+
+}
diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OffCanvasTest.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OffCanvasTest.php
deleted file mode 100644
index a2a9514..0000000
--- a/core/modules/outside_in/tests/src/FunctionalJavascript/OffCanvasTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-namespace Drupal\Tests\outside_in\FunctionalJavascript;
-
-/**
- * Tests the off-canvas tray functionality.
- *
- * @group outside_in
- */
-class OffCanvasTest extends OutsideInJavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['block', 'system', 'toolbar', 'outside_in', 'offcanvas_test'];
-
-  /**
-   * Tests that regular non-contextual links will work with the off-canvas tray.
-   */
-  public function testOffCanvasLinks() {
-    $themes = ['bartik', 'stark'];
-    // Test the same functionality on multiple themes.
-    foreach ($themes as $theme) {
-      $this->enableTheme($theme);
-      $this->drupalGet('/offcanvas-test-links');
-
-      $page = $this->getSession()->getPage();
-      $web_assert = $this->assertSession();
-
-      // Make sure off-canvas tray is on page when first loaded.
-      $web_assert->elementNotExists('css', '#drupal-offcanvas');
-
-      // Check opening and closing with two separate links.
-      // Make sure tray updates to new content.
-      // Check the first link again to make sure the empty title class is
-      // removed.
-      foreach (['1', '2', '1'] as $link_index) {
-        // Click the first test like that should open the page.
-        $page->clickLink("Click Me $link_index!");
-        $this->waitForOffCanvasToOpen();
-
-        // Check that the canvas is not on the page.
-        $web_assert->elementExists('css', '#drupal-offcanvas');
-        // Check that response text is on page.
-        $web_assert->pageTextContains("Thing $link_index says hello");
-        $offcanvas_tray = $this->getTray();
-
-        // Check that tray is visible.
-        $this->assertEquals(TRUE, $offcanvas_tray->isVisible());
-        $header_text = $offcanvas_tray->find('css', '.ui-dialog-title')->getText();
-
-        $tray_text = $offcanvas_tray->findById('drupal-offcanvas')->getText();
-        $this->assertEquals("Thing $link_index says hello", $tray_text);
-
-        // Check no title behavior.
-        if ($link_index == '2') {
-          $web_assert->elementExists('css', '.ui-dialog-empty-title');
-          $this->assertEquals('', $header_text);
-        }
-        else {
-          // Check that header is correct.
-          $this->assertEquals("Thing $link_index", $header_text);
-          $web_assert->elementNotExists('css', '.ui-dialog-empty-title');
-        }
-      }
-    }
-  }
-
-}
diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php
deleted file mode 100644
index dd79fc2..0000000
--- a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-
-namespace Drupal\Tests\outside_in\FunctionalJavascript;
-
-/**
- * Testing opening and saving block forms in the off-canvas tray.
- *
- * @group outside_in
- */
-class OutsideInBlockFormTest extends OutsideInJavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = [
-    'node',
-    'block',
-    'system',
-    'breakpoint',
-    'toolbar',
-    'contextual',
-    'outside_in',
-    'quickedit',
-    'search',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    // @todo Ensure that this test class works against bartik and stark:
-    //   https://www.drupal.org/node/2784881.
-    $this->enableTheme('bartik');
-    $user = $this->createUser([
-      'administer blocks',
-      'access contextual links',
-      'access toolbar',
-      'administer nodes',
-      'access in-place editing',
-      'search content',
-    ]);
-    $this->drupalLogin($user);
-
-    $this->placeBlock('system_powered_by_block', ['id' => 'powered']);
-    $this->placeBlock('system_branding_block', ['id' => 'branding']);
-    $this->placeBlock('search_form_block', ['id' => 'search']);
-  }
-
-  /**
-   * Tests opening Offcanvas tray by click blocks and elements in the blocks.
-   */
-  public function testBlocks() {
-    $blocks = [
-      [
-        'id' => 'block-powered',
-        'new_page_text' => 'Can you imagine anyone showing the label on this block?',
-        'element_selector' => '.content a',
-        'button_text' => 'Save Powered by Drupal',
-      ],
-      [
-        'id' => 'block-branding',
-        'new_page_text' => 'The site that will live a very short life.',
-        'element_selector' => 'a[rel="home"]:nth-child(2)',
-        'button_text' => 'Save Site branding',
-      ],
-      [
-        'id' => 'block-search',
-        'element_selector' => '#edit-submit',
-        'button_text' => 'Save Search form',
-      ],
-    ];
-    $page = $this->getSession()->getPage();
-    foreach ($blocks as $block) {
-      $block_selector = '#' . $block['id'];
-      $this->drupalGet('user');
-      $this->toggleEditingMode();
-      $this->openBlockForm($block_selector);
-
-      switch ($block['id']) {
-        case 'block-powered':
-          // Fill out form, save the form.
-          $page->fillField('settings[label]', $block['new_page_text']);
-          $page->checkField('settings[label_display]');
-          break;
-
-        case 'block-branding':
-          // Fill out form, save the form.
-          $page->fillField('settings[site_information][site_name]', $block['new_page_text']);
-          break;
-      }
-
-      if (isset($block['new_page_text'])) {
-        $page->pressButton($block['button_text']);
-        // Make sure the changes are present.
-        $this->getSession()->wait(500);
-        $web_assert = $this->assertSession();
-        $web_assert->pageTextContains($block['new_page_text']);
-      }
-
-      $this->openBlockForm($block_selector);
-
-      $this->toggleEditingMode();
-      // Canvas should close when editing module is closed.
-      $this->waitForOffCanvasToClose();
-
-      // Go into Edit mode again.
-      $this->toggleEditingMode();
-
-      $element_selector = "$block_selector {$block['element_selector']}";
-      // Open block form by clicking a element inside the block.
-      // This confirms that default action for links and form elements is
-      // suppressed.
-      $this->openBlockForm($element_selector);
-
-      // Exit edit mode.
-      $this->toggleEditingMode();
-    }
-  }
-
-  /**
-   * Enables Editing mode by pressing "Edit" button in the toolbar.
-   */
-  protected function toggleEditingMode() {
-    $this->waitForElement('div[data-contextual-id="block:block=powered:langcode=en|outside_in::langcode=en"] .contextual-links a');
-
-    $this->waitForElement('#toolbar-bar', 3000);
-
-    $edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button');
-
-    $edit_button->press();
-  }
-
-  /**
-   * Asserts that Off-Canvas block form is valid.
-   */
-  protected function assertOffCanvasBlockFormIsValid() {
-    $web_assert = $this->assertSession();
-    // Check that common block form elements exist.
-    $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label"]');
-    $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label-display"]');
-    // Check that advanced block form elements do not exist.
-    $web_assert->elementNotExists('css', 'input[data-drupal-selector="edit-visibility-request-path-pages"]');
-    $web_assert->elementNotExists('css', 'select[data-drupal-selector="edit-region"]');
-  }
-
-  /**
-   * Open block form by clicking the element found with a css selector.
-   *
-   * @param string $block_selector
-   *   A css selector selects the block or an element within it.
-   */
-  protected function openBlockForm($block_selector) {
-    $this->click($block_selector);
-    $this->waitForOffCanvasToOpen();
-    $this->assertOffCanvasBlockFormIsValid();
-  }
-}
diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php
deleted file mode 100644
index da0be1b..0000000
--- a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-namespace Drupal\Tests\outside_in\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Base class contains common test functionality for the Settings Tray module.
- */
-abstract class OutsideInJavascriptTestBase extends JavascriptTestBase {
-
-  /**
-   * Enables a theme.
-   *
-   * @param string $theme
-   *   The theme.
-   */
-  public function enableTheme($theme) {
-    // Enable the theme.
-    \Drupal::service('theme_installer')->install([$theme]);
-    $theme_config = \Drupal::configFactory()->getEditable('system.theme');
-    $theme_config->set('default', $theme);
-    $theme_config->save();
-  }
-
-  /**
-   * Waits for Off-canvas tray to open.
-   */
-  protected function waitForOffCanvasToOpen() {
-    $web_assert = $this->assertSession();
-    $web_assert->assertWaitOnAjaxRequest();
-    $this->waitForElement('#drupal-offcanvas');
-  }
-
-  /**
-   * Waits for Off-canvas tray to close.
-   */
-  protected function waitForOffCanvasToClose() {
-    $condition = "(jQuery('#drupal-offcanvas').length == 0)";
-    $this->assertJsCondition($condition);
-  }
-
-  /**
-   * Waits for an element to appear on the page.
-   *
-   * @param string $selector
-   *   CSS selector.
-   * @param int $timeout
-   *   (optional) Timeout in milliseconds, defaults to 1000.
-   */
-  protected function waitForElement($selector, $timeout = 1000) {
-    $condition = "(jQuery('$selector').length > 0)";
-    $this->assertJsCondition($condition, $timeout);
-  }
-
-  /**
-   * Gets the Off-Canvas tray element.
-   *
-   * @return \Behat\Mink\Element\NodeElement|null
-   */
-  protected function getTray() {
-    $tray = $this->getSession()->getPage()->find('css', '.ui-dialog[aria-describedby="drupal-offcanvas"]');
-    $this->assertEquals(FALSE, empty($tray), 'The tray was found.');
-    return $tray;
-  }
-
-}
diff --git a/core/modules/simpletest/src/TestDiscovery.php b/core/modules/simpletest/src/TestDiscovery.php
index ae5dc52..3d655ef 100644
--- a/core/modules/simpletest/src/TestDiscovery.php
+++ b/core/modules/simpletest/src/TestDiscovery.php
@@ -99,7 +99,7 @@ public function registerTestNamespaces() {
     $this->testNamespaces['Drupal\\Tests\\'] = [$this->root . '/core/tests/Drupal/Tests'];
     $this->testNamespaces['Drupal\\KernelTests\\'] = [$this->root . '/core/tests/Drupal/KernelTests'];
     $this->testNamespaces['Drupal\\FunctionalTests\\'] = [$this->root . '/core/tests/Drupal/FunctionalTests'];
-    $this->testNamespaces['Drupal\\FunctionalJavascriptTests\\'] = [$this->root . '/core/tests/Drupal/FunctionalJavascriptTests'];
+    $this->testNamespaces['Drupal\\FunctionalJavaScriptTests\\'] = [$this->root . '/core/tests/Drupal/FunctionalJavaScriptTests'];
 
     $this->availableExtensions = array();
     foreach ($this->getExtensions() as $name => $extension) {
@@ -118,7 +118,7 @@ public function registerTestNamespaces() {
       $this->testNamespaces["Drupal\\Tests\\$name\\Unit\\"][] = "$base_path/tests/src/Unit";
       $this->testNamespaces["Drupal\\Tests\\$name\\Kernel\\"][] = "$base_path/tests/src/Kernel";
       $this->testNamespaces["Drupal\\Tests\\$name\\Functional\\"][] = "$base_path/tests/src/Functional";
-      $this->testNamespaces["Drupal\\Tests\\$name\\FunctionalJavascript\\"][] = "$base_path/tests/src/FunctionalJavascript";
+      $this->testNamespaces["Drupal\\Tests\\$name\\FunctionalJavaScript\\"][] = "$base_path/tests/src/FunctionalJavaScript";
     }
 
     foreach ($this->testNamespaces as $prefix => $paths) {
diff --git a/core/modules/simpletest/tests/src/FunctionalJavaScript/BrowserWithJavaScriptTest.php b/core/modules/simpletest/tests/src/FunctionalJavaScript/BrowserWithJavaScriptTest.php
new file mode 100644
index 0000000..e326599
--- /dev/null
+++ b/core/modules/simpletest/tests/src/FunctionalJavaScript/BrowserWithJavaScriptTest.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Drupal\Tests\simpletest\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Tests if we can execute JavaScript in the browser.
+ *
+ * @group javascript
+ */
+class BrowserWithJavaScriptTest extends JavaScriptTestBase {
+
+  public function testJavaScript() {
+    $this->drupalGet('<front>');
+    $session = $this->getSession();
+
+    $session->resizeWindow(400, 300);
+    $javascript = <<<JS
+    (function(){
+        var w = window,
+        d = document,
+        e = d.documentElement,
+        g = d.getElementsByTagName('body')[0],
+        x = w.innerWidth || e.clientWidth || g.clientWidth,
+        y = w.innerHeight || e.clientHeight|| g.clientHeight;
+        return x == 400 && y == 300;
+    }());
+JS;
+    $this->assertJsCondition($javascript);
+  }
+
+  public function testAssertJsCondition() {
+    $this->drupalGet('<front>');
+    $session = $this->getSession();
+
+    $session->resizeWindow(500, 300);
+    $javascript = <<<JS
+    (function(){
+        var w = window,
+        d = document,
+        e = d.documentElement,
+        g = d.getElementsByTagName('body')[0],
+        x = w.innerWidth || e.clientWidth || g.clientWidth,
+        y = w.innerHeight || e.clientHeight|| g.clientHeight;
+        return x == 400 && y == 300;
+    }());
+JS;
+
+    // We expected the following assertion to fail because the window has been
+    // re-sized to have a width of 500 not 400.
+    $this->setExpectedException(\PHPUnit_Framework_AssertionFailedError::class);
+    $this->assertJsCondition($javascript, 100);
+  }
+
+  /**
+   * Tests creating screenshots.
+   */
+  public function testCreateScreenshot() {
+    $this->drupalGet('<front>');
+    $this->createScreenshot('public://screenshot.jpg');
+    $this->assertFileExists('public://screenshot.jpg');
+  }
+
+}
diff --git a/core/modules/simpletest/tests/src/FunctionalJavascript/BrowserWithJavascriptTest.php b/core/modules/simpletest/tests/src/FunctionalJavascript/BrowserWithJavascriptTest.php
deleted file mode 100644
index 2439799..0000000
--- a/core/modules/simpletest/tests/src/FunctionalJavascript/BrowserWithJavascriptTest.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-
-namespace Drupal\Tests\simpletest\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests if we can execute JavaScript in the browser.
- *
- * @group javascript
- */
-class BrowserWithJavascriptTest extends JavascriptTestBase {
-
-  public function testJavascript() {
-    $this->drupalGet('<front>');
-    $session = $this->getSession();
-
-    $session->resizeWindow(400, 300);
-    $javascript = <<<JS
-    (function(){
-        var w = window,
-        d = document,
-        e = d.documentElement,
-        g = d.getElementsByTagName('body')[0],
-        x = w.innerWidth || e.clientWidth || g.clientWidth,
-        y = w.innerHeight || e.clientHeight|| g.clientHeight;
-        return x == 400 && y == 300;
-    }());
-JS;
-    $this->assertJsCondition($javascript);
-  }
-
-  public function testAssertJsCondition() {
-    $this->drupalGet('<front>');
-    $session = $this->getSession();
-
-    $session->resizeWindow(500, 300);
-    $javascript = <<<JS
-    (function(){
-        var w = window,
-        d = document,
-        e = d.documentElement,
-        g = d.getElementsByTagName('body')[0],
-        x = w.innerWidth || e.clientWidth || g.clientWidth,
-        y = w.innerHeight || e.clientHeight|| g.clientHeight;
-        return x == 400 && y == 300;
-    }());
-JS;
-
-    // We expected the following assertion to fail because the window has been
-    // re-sized to have a width of 500 not 400.
-    $this->setExpectedException(\PHPUnit_Framework_AssertionFailedError::class);
-    $this->assertJsCondition($javascript, 100);
-  }
-
-  /**
-   * Tests creating screenshots.
-   */
-  public function testCreateScreenshot() {
-    $this->drupalGet('<front>');
-    $this->createScreenshot('public://screenshot.jpg');
-    $this->assertFileExists('public://screenshot.jpg');
-  }
-
-}
diff --git a/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php b/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php
index df98377..4e47656 100644
--- a/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php
+++ b/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php
@@ -401,12 +401,12 @@ public function providerTestGetPhpunitTestSuite() {
     $data['module-unittest'] = [static::class, 'Unit'];
     $data['module-kerneltest'] = ['\Drupal\KernelTests\Core\Theme\TwigMarkupInterfaceTest', 'Kernel'];
     $data['module-functionaltest'] = ['\Drupal\FunctionalTests\BrowserTestBaseTest', 'Functional'];
-    $data['module-functionaljavascripttest'] = ['\Drupal\Tests\toolbar\FunctionalJavascript\ToolbarIntegrationTest', 'FunctionalJavascript'];
+    $data['module-functionaljavascripttest'] = ['\Drupal\Tests\toolbar\FunctionalJavaScript\ToolbarIntegrationTest', 'FunctionalJavaScript'];
     $data['core-unittest'] = ['\Drupal\Tests\ComposerIntegrationTest', 'Unit'];
     $data['core-unittest2'] = ['Drupal\Tests\Core\DrupalTest', 'Unit'];
     $data['core-kerneltest'] = ['\Drupal\KernelTests\KernelTestBaseTest', 'Kernel'];
     $data['core-functionaltest'] = ['\Drupal\FunctionalTests\ExampleTest', 'Functional'];
-    $data['core-functionaljavascripttest'] = ['\Drupal\FunctionalJavascriptTests\ExampleTest', 'FunctionalJavascript'];
+    $data['core-functionaljavascripttest'] = ['\Drupal\FunctionalJavaScriptTests\ExampleTest', 'FunctionalJavaScript'];
 
     return $data;
   }
diff --git a/core/modules/system/css/components/js.module.css b/core/modules/system/css/components/js.module.css
index f827020..f6c1c01 100644
--- a/core/modules/system/css/components/js.module.css
+++ b/core/modules/system/css/components/js.module.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Utility classes to assist with Javascript functionality.
+ * Utility classes to assist with JavaScript functionality.
  */
 
 /**
diff --git a/core/modules/system/src/Tests/Routing/DestinationTest.php b/core/modules/system/src/Tests/Routing/DestinationTest.php
index d959c7a..6b61cc4 100644
--- a/core/modules/system/src/Tests/Routing/DestinationTest.php
+++ b/core/modules/system/src/Tests/Routing/DestinationTest.php
@@ -55,7 +55,7 @@ public function testDestination() {
       [
         'input' => 'javascript:alert(0)',
         'output' => 'javascript:alert(0)',
-        'message' => 'Javascript URL is allowed because it is treated as an internal URL.',
+        'message' => 'JavaScript URL is allowed because it is treated as an internal URL.',
       ],
     ];
     foreach ($test_cases as $test_case) {
diff --git a/core/modules/toolbar/tests/src/FunctionalJavaScript/ToolbarIntegrationTest.php b/core/modules/toolbar/tests/src/FunctionalJavaScript/ToolbarIntegrationTest.php
new file mode 100644
index 0000000..f86e9da
--- /dev/null
+++ b/core/modules/toolbar/tests/src/FunctionalJavaScript/ToolbarIntegrationTest.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Drupal\Tests\toolbar\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Tests the JavaScript functionality of the toolbar.
+ *
+ * @group toolbar
+ */
+class ToolbarIntegrationTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['toolbar', 'node'];
+
+  /**
+   * Tests if the toolbar can be toggled with JavaScript.
+   */
+  public function testToolbarToggling() {
+    $admin_user = $this->drupalCreateUser([
+      'access toolbar',
+      'administer site configuration',
+      'access content overview',
+    ]);
+    $this->drupalLogin($admin_user);
+
+    $this->drupalGet('<front>');
+    $page = $this->getSession()->getPage();
+
+    // Test that it is possible to toggle the toolbar tray.
+    $content = $page->findLink('Content');
+    $this->assertTrue($content->isVisible(), 'Toolbar tray is open by default.');
+    $page->clickLink('Manage');
+    $this->assertFalse($content->isVisible(), 'Toolbar tray is closed after clicking the "Manage" link.');
+    $page->clickLink('Manage');
+    $this->assertTrue($content->isVisible(), 'Toolbar tray is visible again after clicking the "Manage" button a second time.');
+
+    // Test toggling the toolbar tray between horizontal and vertical.
+    $tray = $page->findById('toolbar-item-administration-tray');
+    $this->assertFalse($tray->hasClass('toolbar-tray-vertical'), 'Toolbar tray is not vertically oriented by default.');
+    $page->pressButton('Vertical orientation');
+    $this->assertTrue($tray->hasClass('toolbar-tray-vertical'), 'After toggling the orientation the toolbar tray is now displayed vertically.');
+
+    $page->pressButton('Horizontal orientation');
+    $this->assertTrue($tray->hasClass('toolbar-tray-horizontal'), 'After toggling the orientation a second time the toolbar tray is displayed horizontally again.');
+  }
+
+}
diff --git a/core/modules/toolbar/tests/src/FunctionalJavascript/ToolbarIntegrationTest.php b/core/modules/toolbar/tests/src/FunctionalJavascript/ToolbarIntegrationTest.php
deleted file mode 100644
index c3b3d9a..0000000
--- a/core/modules/toolbar/tests/src/FunctionalJavascript/ToolbarIntegrationTest.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-namespace Drupal\Tests\toolbar\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests the JavaScript functionality of the toolbar.
- *
- * @group toolbar
- */
-class ToolbarIntegrationTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['toolbar', 'node'];
-
-  /**
-   * Tests if the toolbar can be toggled with JavaScript.
-   */
-  public function testToolbarToggling() {
-    $admin_user = $this->drupalCreateUser([
-      'access toolbar',
-      'administer site configuration',
-      'access content overview',
-    ]);
-    $this->drupalLogin($admin_user);
-
-    $this->drupalGet('<front>');
-    $page = $this->getSession()->getPage();
-
-    // Test that it is possible to toggle the toolbar tray.
-    $content = $page->findLink('Content');
-    $this->assertTrue($content->isVisible(), 'Toolbar tray is open by default.');
-    $page->clickLink('Manage');
-    $this->assertFalse($content->isVisible(), 'Toolbar tray is closed after clicking the "Manage" link.');
-    $page->clickLink('Manage');
-    $this->assertTrue($content->isVisible(), 'Toolbar tray is visible again after clicking the "Manage" button a second time.');
-
-    // Test toggling the toolbar tray between horizontal and vertical.
-    $tray = $page->findById('toolbar-item-administration-tray');
-    $this->assertFalse($tray->hasClass('toolbar-tray-vertical'), 'Toolbar tray is not vertically oriented by default.');
-    $page->pressButton('Vertical orientation');
-    $this->assertTrue($tray->hasClass('toolbar-tray-vertical'), 'After toggling the orientation the toolbar tray is now displayed vertically.');
-
-    $page->pressButton('Horizontal orientation');
-    $this->assertTrue($tray->hasClass('toolbar-tray-horizontal'), 'After toggling the orientation a second time the toolbar tray is displayed horizontally again.');
-  }
-
-}
diff --git a/core/modules/views/config/schema/views.style.schema.yml b/core/modules/views/config/schema/views.style.schema.yml
index 49de11b..f31f67a 100644
--- a/core/modules/views/config/schema/views.style.schema.yml
+++ b/core/modules/views/config/schema/views.style.schema.yml
@@ -91,7 +91,7 @@ views.style.table:
       label: 'Override normal sorting if click sorting is used'
     sticky:
       type: boolean
-      label: 'Enable Drupal style "sticky" table headers (Javascript)'
+      label: 'Enable Drupal style "sticky" table headers (JavaScript)'
     summary:
       type: label
       label: 'Summary title'
diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js
index 6422dd0..9a932fb 100644
--- a/core/modules/views/js/ajax_view.js
+++ b/core/modules/views/js/ajax_view.js
@@ -38,7 +38,7 @@
   Drupal.views.instances = {};
 
   /**
-   * Javascript object for a certain view.
+   * JavaScript object for a certain view.
    *
    * @constructor
    *
diff --git a/core/modules/views/src/Plugin/views/style/Table.php b/core/modules/views/src/Plugin/views/style/Table.php
index c49f6e9..ed577db 100644
--- a/core/modules/views/src/Plugin/views/style/Table.php
+++ b/core/modules/views/src/Plugin/views/style/Table.php
@@ -216,7 +216,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
 
     $form['sticky'] = array(
       '#type' => 'checkbox',
-      '#title' => $this->t('Enable Drupal style "sticky" table headers (Javascript)'),
+      '#title' => $this->t('Enable Drupal style "sticky" table headers (JavaScript)'),
       '#default_value' => !empty($this->options['sticky']),
       '#description' => $this->t('(Sticky header effects will not be active for preview below, only on live output.)'),
     );
diff --git a/core/modules/views/templates/views-view.html.twig b/core/modules/views/templates/views-view.html.twig
index e81b1ab..a71ffe9 100644
--- a/core/modules/views/templates/views-view.html.twig
+++ b/core/modules/views/templates/views-view.html.twig
@@ -25,7 +25,7 @@
  * - attachment_after: An optional attachment view to be displayed after the
  *   view content.
  * - dom_id: Unique id for every view being printed to give unique class for
- *   Javascript.
+ *   JavaScript.
  *
  * @see template_preprocess_views_view()
  *
diff --git a/core/modules/views/tests/src/FunctionalJavaScript/ClickSortingAJAXTest.php b/core/modules/views/tests/src/FunctionalJavaScript/ClickSortingAJAXTest.php
new file mode 100644
index 0000000..7dda31b
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavaScript/ClickSortingAJAXTest.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\simpletest\NodeCreationTrait;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the click sorting AJAX functionality of Views exposed forms.
+ *
+ * @group views
+ */
+class ClickSortingAJAXTest extends JavaScriptTestBase {
+
+  use ContentTypeCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_test_config'];
+
+  public static $testViews = ['test_content_ajax'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    ViewTestData::createTestViews(self::class, ['views_test_config']);
+
+    // Create a Content type and two test nodes.
+    $this->createContentType(['type' => 'page']);
+    $this->createNode(['title' => 'Page A', 'changed' => REQUEST_TIME]);
+    $this->createNode(['title' => 'Page B', 'changed' => REQUEST_TIME + 1000]);
+
+    // Create a user privileged enough to view content.
+    $user = $this->drupalCreateUser([
+      'administer site configuration',
+      'access content',
+      'access content overview',
+    ]);
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Tests if sorting via AJAX works for the "Content" View.
+   */
+  public function testClickSorting() {
+    // Visit the content page.
+    $this->drupalGet('test-content-ajax');
+
+    $session_assert = $this->assertSession();
+
+    $page = $this->getSession()->getPage();
+
+    // Ensure that the Content we're testing for is in the right order, default
+    // sorting is by changed timestamp so the last created node should be first.
+    /** @var \Behat\Mink\Element\NodeElement[] $rows */
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(2, $rows);
+    $this->assertContains('Page B', $rows[0]->getHtml());
+    $this->assertContains('Page A', $rows[1]->getHtml());
+
+    // Now sort by title and check if the order changed.
+    $page->clickLink('Title');
+    $session_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(2, $rows);
+    $this->assertContains('Page A', $rows[0]->getHtml());
+    $this->assertContains('Page B', $rows[1]->getHtml());
+  }
+
+}
diff --git a/core/modules/views/tests/src/FunctionalJavaScript/ExposedFilterAJAXTest.php b/core/modules/views/tests/src/FunctionalJavaScript/ExposedFilterAJAXTest.php
new file mode 100644
index 0000000..9b65ac0
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavaScript/ExposedFilterAJAXTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\simpletest\NodeCreationTrait;
+
+/**
+ * Tests the basic AJAX functionality of Views exposed forms.
+ *
+ * @group views
+ */
+class ExposedFilterAJAXTest extends JavaScriptTestBase {
+
+  use ContentTypeCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views'];
+
+  /**
+   * Tests if exposed filtering via AJAX works for the "Content" View.
+   */
+  public function testExposedFiltering() {
+    // Enable AJAX on the /admin/content View.
+    \Drupal::configFactory()->getEditable('views.view.content')
+      ->set('display.default.display_options.use_ajax', TRUE)
+      ->save();
+
+    // Create a Content type and two test nodes.
+    $this->createContentType(['type' => 'page']);
+    $this->createNode(['title' => 'Page One']);
+    $this->createNode(['title' => 'Page Two']);
+
+    // Create a user privileged enough to use exposed filters and view content.
+    $user = $this->drupalCreateUser([
+      'administer site configuration',
+      'access content',
+      'access content overview',
+    ]);
+    $this->drupalLogin($user);
+
+    // Visit the View page.
+    $this->drupalGet('admin/content');
+
+    $session = $this->getSession();
+
+    // Ensure that the Content we're testing for is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page One', $html);
+    $this->assertContains('Page Two', $html);
+
+    // Search for "Page One".
+    $this->submitForm(['title' => 'Page One'], t('Filter'));
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Verify that only the "Page One" Node is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page One', $html);
+    $this->assertNotContains('Page Two', $html);
+
+    // Search for "Page Two".
+    $this->submitForm(['title' => 'Page Two'], t('Filter'));
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Verify that only the "Page Two" Node is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page Two', $html);
+    $this->assertNotContains('Page One', $html);
+
+    // Reset the form.
+    $this->submitForm([], t('Reset'));
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    $this->assertSession()->pageTextContains('Page One');
+    $this->assertSession()->pageTextContains('Page Two');
+    $this->assertFalse($session->getPage()->hasButton('Reset'));
+  }
+
+}
diff --git a/core/modules/views/tests/src/FunctionalJavaScript/GlossaryViewTest.php b/core/modules/views/tests/src/FunctionalJavaScript/GlossaryViewTest.php
new file mode 100644
index 0000000..0cb44f8
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavaScript/GlossaryViewTest.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavaScript;
+
+use Drupal\Core\Url;
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\simpletest\NodeCreationTrait;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the basic AJAX functionality of the Glossary View.
+ *
+ * @group node
+ */
+class GlossaryViewTest extends JavaScriptTestBase {
+
+  use ContentTypeCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['language', 'node', 'views', 'views_test_config'];
+
+  /**
+   * @var array
+   * The test Views to enable.
+   */
+  public static $testViews = ['test_glossary'];
+
+  /**
+   * @var
+   * The additional language to use.
+   */
+  protected $language;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    ViewTestData::createTestViews(get_class($this), array('views_test_config'));
+
+    // Create a Content type and some test nodes with titles that start with
+    // different letters.
+    $this->createContentType(['type' => 'page']);
+
+    $titles = [
+      'Page One',
+      'Page Two',
+      'Another page',
+    ];
+    foreach ($titles as $title) {
+      $this->createNode([
+        'title' => $title,
+        'language' => 'en',
+      ]);
+      $this->createNode([
+        'title' => $title,
+        'language' => 'nl',
+      ]);
+    }
+
+    // Create a user privileged enough to use exposed filters and view content.
+    $user = $this->drupalCreateUser([
+      'administer site configuration',
+      'access content',
+      'access content overview',
+    ]);
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Tests the AJAX callbacks for the glossary view.
+   */
+  public function testGlossaryDefault() {
+    // Visit the default Glossary page.
+    $url = Url::fromRoute('view.test_glossary.page_1');
+    $this->drupalGet($url);
+
+    $session = $this->getSession();
+    $web_assert = $this->assertSession();
+
+    $page = $session->getPage();
+    $rows = $page->findAll('css', '.view-test-glossary tr');
+    // We expect 2 rows plus the header row.
+    $this->assertCount(3, $rows);
+    // Click on the P link, this should show 4 rows plus the header row.
+    $page->clickLink('P');
+    $web_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', '.view-test-glossary tr');
+    $this->assertCount(5, $rows);
+  }
+
+  /**
+   * Test that the glossary also works on a language prefixed URL.
+   */
+  public function testGlossaryLanguagePrefix() {
+    $this->language = ConfigurableLanguage::createFromLangcode('nl')->save();
+
+    $config = $this->config('language.negotiation');
+    $config->set('url.prefixes', ['en' => 'en', 'nl' => 'nl'])
+      ->save();
+
+    \Drupal::service('kernel')->rebuildContainer();
+
+    $url = Url::fromRoute('view.test_glossary.page_1');
+    $this->drupalGet($url);
+
+    $session = $this->getSession();
+    $web_assert = $this->assertSession();
+
+    $page = $session->getPage();
+
+    $rows = $page->findAll('css', '.view-test-glossary tr');
+    // We expect 2 rows plus the header row.
+    $this->assertCount(3, $rows);
+    // Click on the P link, this should show 4 rows plus the header row.
+    $page->clickLink('P');
+    $web_assert->assertWaitOnAjaxRequest();
+
+    $rows = $page->findAll('css', '.view-test-glossary tr');
+    $this->assertCount(5, $rows);
+  }
+
+}
diff --git a/core/modules/views/tests/src/FunctionalJavaScript/PaginationAJAXTest.php b/core/modules/views/tests/src/FunctionalJavaScript/PaginationAJAXTest.php
new file mode 100644
index 0000000..ac4f698
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavaScript/PaginationAJAXTest.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\simpletest\NodeCreationTrait;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the click sorting AJAX functionality of Views exposed forms.
+ *
+ * @group views
+ */
+class PaginationAJAXTest extends JavaScriptTestBase {
+
+  use ContentTypeCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_test_config'];
+
+  /**
+   * @var array
+   * Test Views to enable.
+   */
+  public static $testViews = ['test_content_ajax'];
+
+  protected $user;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    ViewTestData::createTestViews(self::class, ['views_test_config']);
+
+    // Create a Content type and eleven test nodes.
+    $this->createContentType(['type' => 'page']);
+    for ($i = 1; $i <= 11; $i++) {
+      $this->createNode(['title' => 'Node ' . $i . ' content', 'changed' => $i * 1000]);
+    }
+
+    // Create a user privileged enough to view content.
+    $user = $this->drupalCreateUser([
+      'administer site configuration',
+      'access content',
+      'access content overview',
+    ]);
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Tests if pagination via AJAX works for the "Content" View.
+   */
+  public function testBasicPagination() {
+    // Visit the content page.
+    $this->drupalGet('test-content-ajax');
+
+    $session_assert = $this->assertSession();
+
+    $page = $this->getSession()->getPage();
+
+    // Set the number of items displayed per page to 5 using the exposed pager.
+    $page->selectFieldOption('edit-items-per-page', 5);
+    $page->pressButton('Filter');
+    $session_assert->assertWaitOnAjaxRequest();
+
+    // Change 'Updated' sorting from descending to ascending.
+    $page->clickLink('Updated');
+    $session_assert->assertWaitOnAjaxRequest();
+
+    // Use the pager by clicking on the links and test if we see the expected
+    // number of rows on each page. For easy targeting the titles of the pager
+    // links are used.
+    /** @var \Behat\Mink\Element\NodeElement[] $rows */
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(5, $rows);
+    $this->assertContains('Node 1 content', $rows[0]->getHtml());
+
+    $this->clickLink('Go to page 2');
+    $session_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(5, $rows);
+    $this->assertContains('Node 6 content', $rows[0]->getHtml());
+
+    $this->clickLink('Go to page 3');
+    $session_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(1, $rows);
+    $this->assertContains('Node 11 content', $rows[0]->getHtml());
+
+    // Navigate back to the first page.
+    $this->clickLink('Go to first page');
+    $session_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(5, $rows);
+    $this->assertContains('Node 1 content', $rows[0]->getHtml());
+
+    // Navigate using the 'next' link.
+    $this->clickLink('Go to next page');
+    $session_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(5, $rows);
+    $this->assertContains('Node 6 content', $rows[0]->getHtml());
+
+    // Navigate using the 'last' link.
+    $this->clickLink('Go to last page');
+    $session_assert->assertWaitOnAjaxRequest();
+    $rows = $page->findAll('css', 'tbody tr');
+    $this->assertCount(1, $rows);
+    $this->assertContains('Node 11 content', $rows[0]->getHtml());
+  }
+
+}
diff --git a/core/modules/views/tests/src/FunctionalJavaScript/Plugin/views/Handler/ContextualFilterTest.php b/core/modules/views/tests/src/FunctionalJavaScript/Plugin/views/Handler/ContextualFilterTest.php
new file mode 100644
index 0000000..d033c74
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavaScript/Plugin/views/Handler/ContextualFilterTest.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavaScript\Plugin\views\Handler;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the contextual filter handler UI.
+ *
+ * @group views
+ */
+class ContextualFilterTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_ui', 'views_test_config'];
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_field_body'];
+
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    ViewTestData::createTestViews(get_class($this), ['views_test_config']);
+
+    // Disable automatic live preview to make the sequence of calls clearer.
+    \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.advanced_column', TRUE)->save();
+
+    $account = $this->drupalCreateUser(['administer views']);
+    $this->drupalLogin($account);
+  }
+
+  /**
+   * Test adding a contextual filter handler through the UI.
+   */
+  public function testAddContextualFilterUI() {
+    $web_assert = $this->assertSession();
+
+    $this->drupalGet('/admin/structure/views/view/test_field_body');
+    $web_assert->assertWaitOnAjaxRequest();
+
+    $page = $this->getSession()->getPage();
+
+    $page->clickLink('views-add-argument');
+    $web_assert->assertWaitOnAjaxRequest();
+
+    $page->checkField('name[node_field_data.nid]');
+    $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
+    $add_button->click();
+    $web_assert->assertWaitOnAjaxRequest();
+
+    $page->fillField('options[default_action]', 'default');
+    $page->selectFieldOption('options[default_argument_type]', 'node');
+    $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
+    $add_button->click();
+    $web_assert->assertWaitOnAjaxRequest();
+    $page->pressButton('edit-actions-submit');
+    $web_assert->assertWaitOnAjaxRequest();
+    $page->clickLink('Content: ID');
+    // Check that the dialog opens.
+    $web_assert->assertWaitOnAjaxRequest();
+    $page->pressButton('Close');
+  }
+
+}
diff --git a/core/modules/views/tests/src/FunctionalJavaScript/Plugin/views/Handler/FieldTest.php b/core/modules/views/tests/src/FunctionalJavaScript/Plugin/views/Handler/FieldTest.php
new file mode 100644
index 0000000..b21da58
--- /dev/null
+++ b/core/modules/views/tests/src/FunctionalJavaScript/Plugin/views/Handler/FieldTest.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Drupal\Tests\views\FunctionalJavaScript\Plugin\views\Handler;
+
+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 FieldTest extends JavaScriptTestBase {
+  use SchemaCheckTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_ui', 'views_test_config'];
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_field_body'];
+
+  /**
+   * The account.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $account;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    ViewTestData::createTestViews(get_class($this), ['views_test_config']);
+
+    // 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();
+  }
+
+  public function testFormatterChanging() {
+    $web_assert = $this->assertSession();
+    $url = '/admin/structure/views/view/test_field_body';
+    $this->drupalGet($url);
+
+    $page = $this->getSession()->getPage();
+
+    $page->clickLink('Body field');
+    $web_assert->assertWaitOnAjaxRequest();
+
+    $page->fillField('options[type]', 'text_trimmed');
+    // Add a value to the trim_length setting.
+    $web_assert->assertWaitOnAjaxRequest();
+    $page->fillField('options[settings][trim_length]', '700');
+    $apply_button = $page->find('css', '.views-ui-dialog button.button--primary');
+    $this->assertTrue(!empty($apply_button));
+    $apply_button->press();
+    $web_assert->assertWaitOnAjaxRequest();
+
+    // Save the page.
+    $save_button = $page->find('css', '#edit-actions-submit');
+    $save_button->press();
+
+    // Set the body field back to 'default' and test that the trim_length
+    // settings are not in the config.
+    $this->drupalGet($url);
+    $page->clickLink('Body field');
+    $web_assert->assertWaitOnAjaxRequest();
+
+    $page->fillField('options[type]', 'text_default');
+    $web_assert->assertWaitOnAjaxRequest();
+    $apply_button = $page->find('css', '.views-ui-dialog button.button--primary');
+    $apply_button->press();
+    $web_assert->assertWaitOnAjaxRequest();
+
+    // Save the page.
+    $save_button = $page->find('css', '#edit-actions-submit');
+    $save_button->press();
+
+    $this->assertConfigSchemaByName('views.view.test_field_body');
+  }
+
+}
diff --git a/core/modules/views/tests/src/FunctionalJavascript/ClickSortingAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/ClickSortingAJAXTest.php
deleted file mode 100644
index 0e5095d..0000000
--- a/core/modules/views/tests/src/FunctionalJavascript/ClickSortingAJAXTest.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\simpletest\ContentTypeCreationTrait;
-use Drupal\simpletest\NodeCreationTrait;
-use Drupal\views\Tests\ViewTestData;
-
-/**
- * Tests the click sorting AJAX functionality of Views exposed forms.
- *
- * @group views
- */
-class ClickSortingAJAXTest extends JavascriptTestBase {
-
-  use ContentTypeCreationTrait;
-  use NodeCreationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_test_config'];
-
-  public static $testViews = ['test_content_ajax'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    ViewTestData::createTestViews(self::class, ['views_test_config']);
-
-    // Create a Content type and two test nodes.
-    $this->createContentType(['type' => 'page']);
-    $this->createNode(['title' => 'Page A', 'changed' => REQUEST_TIME]);
-    $this->createNode(['title' => 'Page B', 'changed' => REQUEST_TIME + 1000]);
-
-    // Create a user privileged enough to view content.
-    $user = $this->drupalCreateUser([
-      'administer site configuration',
-      'access content',
-      'access content overview',
-    ]);
-    $this->drupalLogin($user);
-  }
-
-  /**
-   * Tests if sorting via AJAX works for the "Content" View.
-   */
-  public function testClickSorting() {
-    // Visit the content page.
-    $this->drupalGet('test-content-ajax');
-
-    $session_assert = $this->assertSession();
-
-    $page = $this->getSession()->getPage();
-
-    // Ensure that the Content we're testing for is in the right order, default
-    // sorting is by changed timestamp so the last created node should be first.
-    /** @var \Behat\Mink\Element\NodeElement[] $rows */
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(2, $rows);
-    $this->assertContains('Page B', $rows[0]->getHtml());
-    $this->assertContains('Page A', $rows[1]->getHtml());
-
-    // Now sort by title and check if the order changed.
-    $page->clickLink('Title');
-    $session_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(2, $rows);
-    $this->assertContains('Page A', $rows[0]->getHtml());
-    $this->assertContains('Page B', $rows[1]->getHtml());
-  }
-
-}
diff --git a/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
deleted file mode 100644
index 974aa2d..0000000
--- a/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\simpletest\ContentTypeCreationTrait;
-use Drupal\simpletest\NodeCreationTrait;
-
-/**
- * Tests the basic AJAX functionality of Views exposed forms.
- *
- * @group views
- */
-class ExposedFilterAJAXTest extends JavascriptTestBase {
-
-  use ContentTypeCreationTrait;
-  use NodeCreationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views'];
-
-  /**
-   * Tests if exposed filtering via AJAX works for the "Content" View.
-   */
-  public function testExposedFiltering() {
-    // Enable AJAX on the /admin/content View.
-    \Drupal::configFactory()->getEditable('views.view.content')
-      ->set('display.default.display_options.use_ajax', TRUE)
-      ->save();
-
-    // Create a Content type and two test nodes.
-    $this->createContentType(['type' => 'page']);
-    $this->createNode(['title' => 'Page One']);
-    $this->createNode(['title' => 'Page Two']);
-
-    // Create a user privileged enough to use exposed filters and view content.
-    $user = $this->drupalCreateUser([
-      'administer site configuration',
-      'access content',
-      'access content overview',
-    ]);
-    $this->drupalLogin($user);
-
-    // Visit the View page.
-    $this->drupalGet('admin/content');
-
-    $session = $this->getSession();
-
-    // Ensure that the Content we're testing for is present.
-    $html = $session->getPage()->getHtml();
-    $this->assertContains('Page One', $html);
-    $this->assertContains('Page Two', $html);
-
-    // Search for "Page One".
-    $this->submitForm(['title' => 'Page One'], t('Filter'));
-    $this->assertSession()->assertWaitOnAjaxRequest();
-
-    // Verify that only the "Page One" Node is present.
-    $html = $session->getPage()->getHtml();
-    $this->assertContains('Page One', $html);
-    $this->assertNotContains('Page Two', $html);
-
-    // Search for "Page Two".
-    $this->submitForm(['title' => 'Page Two'], t('Filter'));
-    $this->assertSession()->assertWaitOnAjaxRequest();
-
-    // Verify that only the "Page Two" Node is present.
-    $html = $session->getPage()->getHtml();
-    $this->assertContains('Page Two', $html);
-    $this->assertNotContains('Page One', $html);
-
-    // Reset the form.
-    $this->submitForm([], t('Reset'));
-    $this->assertSession()->assertWaitOnAjaxRequest();
-
-    $this->assertSession()->pageTextContains('Page One');
-    $this->assertSession()->pageTextContains('Page Two');
-    $this->assertFalse($session->getPage()->hasButton('Reset'));
-  }
-
-}
diff --git a/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php b/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php
deleted file mode 100644
index 42da7b6..0000000
--- a/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views\FunctionalJavascript;
-
-use Drupal\Core\Url;
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\ContentTypeCreationTrait;
-use Drupal\simpletest\NodeCreationTrait;
-use Drupal\views\Tests\ViewTestData;
-
-/**
- * Tests the basic AJAX functionality of the Glossary View.
- *
- * @group node
- */
-class GlossaryViewTest extends JavascriptTestBase {
-
-  use ContentTypeCreationTrait;
-  use NodeCreationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['language', 'node', 'views', 'views_test_config'];
-
-  /**
-   * @var array
-   * The test Views to enable.
-   */
-  public static $testViews = ['test_glossary'];
-
-  /**
-   * @var
-   * The additional language to use.
-   */
-  protected $language;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    ViewTestData::createTestViews(get_class($this), array('views_test_config'));
-
-    // Create a Content type and some test nodes with titles that start with
-    // different letters.
-    $this->createContentType(['type' => 'page']);
-
-    $titles = [
-      'Page One',
-      'Page Two',
-      'Another page',
-    ];
-    foreach ($titles as $title) {
-      $this->createNode([
-        'title' => $title,
-        'language' => 'en',
-      ]);
-      $this->createNode([
-        'title' => $title,
-        'language' => 'nl',
-      ]);
-    }
-
-    // Create a user privileged enough to use exposed filters and view content.
-    $user = $this->drupalCreateUser([
-      'administer site configuration',
-      'access content',
-      'access content overview',
-    ]);
-    $this->drupalLogin($user);
-  }
-
-  /**
-   * Tests the AJAX callbacks for the glossary view.
-   */
-  public function testGlossaryDefault() {
-    // Visit the default Glossary page.
-    $url = Url::fromRoute('view.test_glossary.page_1');
-    $this->drupalGet($url);
-
-    $session = $this->getSession();
-    $web_assert = $this->assertSession();
-
-    $page = $session->getPage();
-    $rows = $page->findAll('css', '.view-test-glossary tr');
-    // We expect 2 rows plus the header row.
-    $this->assertCount(3, $rows);
-    // Click on the P link, this should show 4 rows plus the header row.
-    $page->clickLink('P');
-    $web_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', '.view-test-glossary tr');
-    $this->assertCount(5, $rows);
-  }
-
-  /**
-   * Test that the glossary also works on a language prefixed URL.
-   */
-  public function testGlossaryLanguagePrefix() {
-    $this->language = ConfigurableLanguage::createFromLangcode('nl')->save();
-
-    $config = $this->config('language.negotiation');
-    $config->set('url.prefixes', ['en' => 'en', 'nl' => 'nl'])
-      ->save();
-
-    \Drupal::service('kernel')->rebuildContainer();
-
-    $url = Url::fromRoute('view.test_glossary.page_1');
-    $this->drupalGet($url);
-
-    $session = $this->getSession();
-    $web_assert = $this->assertSession();
-
-    $page = $session->getPage();
-
-    $rows = $page->findAll('css', '.view-test-glossary tr');
-    // We expect 2 rows plus the header row.
-    $this->assertCount(3, $rows);
-    // Click on the P link, this should show 4 rows plus the header row.
-    $page->clickLink('P');
-    $web_assert->assertWaitOnAjaxRequest();
-
-    $rows = $page->findAll('css', '.view-test-glossary tr');
-    $this->assertCount(5, $rows);
-  }
-
-}
diff --git a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
deleted file mode 100644
index 850c553..0000000
--- a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php
+++ /dev/null
@@ -1,118 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\simpletest\ContentTypeCreationTrait;
-use Drupal\simpletest\NodeCreationTrait;
-use Drupal\views\Tests\ViewTestData;
-
-/**
- * Tests the click sorting AJAX functionality of Views exposed forms.
- *
- * @group views
- */
-class PaginationAJAXTest extends JavascriptTestBase {
-
-  use ContentTypeCreationTrait;
-  use NodeCreationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_test_config'];
-
-  /**
-   * @var array
-   * Test Views to enable.
-   */
-  public static $testViews = ['test_content_ajax'];
-
-  protected $user;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    ViewTestData::createTestViews(self::class, ['views_test_config']);
-
-    // Create a Content type and eleven test nodes.
-    $this->createContentType(['type' => 'page']);
-    for ($i = 1; $i <= 11; $i++) {
-      $this->createNode(['title' => 'Node ' . $i . ' content', 'changed' => $i * 1000]);
-    }
-
-    // Create a user privileged enough to view content.
-    $user = $this->drupalCreateUser([
-      'administer site configuration',
-      'access content',
-      'access content overview',
-    ]);
-    $this->drupalLogin($user);
-  }
-
-  /**
-   * Tests if pagination via AJAX works for the "Content" View.
-   */
-  public function testBasicPagination() {
-    // Visit the content page.
-    $this->drupalGet('test-content-ajax');
-
-    $session_assert = $this->assertSession();
-
-    $page = $this->getSession()->getPage();
-
-    // Set the number of items displayed per page to 5 using the exposed pager.
-    $page->selectFieldOption('edit-items-per-page', 5);
-    $page->pressButton('Filter');
-    $session_assert->assertWaitOnAjaxRequest();
-
-    // Change 'Updated' sorting from descending to ascending.
-    $page->clickLink('Updated');
-    $session_assert->assertWaitOnAjaxRequest();
-
-    // Use the pager by clicking on the links and test if we see the expected
-    // number of rows on each page. For easy targeting the titles of the pager
-    // links are used.
-    /** @var \Behat\Mink\Element\NodeElement[] $rows */
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(5, $rows);
-    $this->assertContains('Node 1 content', $rows[0]->getHtml());
-
-    $this->clickLink('Go to page 2');
-    $session_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(5, $rows);
-    $this->assertContains('Node 6 content', $rows[0]->getHtml());
-
-    $this->clickLink('Go to page 3');
-    $session_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(1, $rows);
-    $this->assertContains('Node 11 content', $rows[0]->getHtml());
-
-    // Navigate back to the first page.
-    $this->clickLink('Go to first page');
-    $session_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(5, $rows);
-    $this->assertContains('Node 1 content', $rows[0]->getHtml());
-
-    // Navigate using the 'next' link.
-    $this->clickLink('Go to next page');
-    $session_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(5, $rows);
-    $this->assertContains('Node 6 content', $rows[0]->getHtml());
-
-    // Navigate using the 'last' link.
-    $this->clickLink('Go to last page');
-    $session_assert->assertWaitOnAjaxRequest();
-    $rows = $page->findAll('css', 'tbody tr');
-    $this->assertCount(1, $rows);
-    $this->assertContains('Node 11 content', $rows[0]->getHtml());
-  }
-
-}
diff --git a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php
deleted file mode 100644
index 8cca9c3..0000000
--- a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\views\Tests\ViewTestData;
-
-/**
- * Tests the contextual filter handler UI.
- *
- * @group views
- */
-class ContextualFilterTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_ui', 'views_test_config'];
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = ['test_field_body'];
-
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    ViewTestData::createTestViews(get_class($this), ['views_test_config']);
-
-    // Disable automatic live preview to make the sequence of calls clearer.
-    \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.advanced_column', TRUE)->save();
-
-    $account = $this->drupalCreateUser(['administer views']);
-    $this->drupalLogin($account);
-  }
-
-  /**
-   * Test adding a contextual filter handler through the UI.
-   */
-  public function testAddContextualFilterUI() {
-    $web_assert = $this->assertSession();
-
-    $this->drupalGet('/admin/structure/views/view/test_field_body');
-    $web_assert->assertWaitOnAjaxRequest();
-
-    $page = $this->getSession()->getPage();
-
-    $page->clickLink('views-add-argument');
-    $web_assert->assertWaitOnAjaxRequest();
-
-    $page->checkField('name[node_field_data.nid]');
-    $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
-    $add_button->click();
-    $web_assert->assertWaitOnAjaxRequest();
-
-    $page->fillField('options[default_action]', 'default');
-    $page->selectFieldOption('options[default_argument_type]', 'node');
-    $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary');
-    $add_button->click();
-    $web_assert->assertWaitOnAjaxRequest();
-    $page->pressButton('edit-actions-submit');
-    $web_assert->assertWaitOnAjaxRequest();
-    $page->clickLink('Content: ID');
-    // Check that the dialog opens.
-    $web_assert->assertWaitOnAjaxRequest();
-    $page->pressButton('Close');
-  }
-
-}
diff --git a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php
deleted file mode 100644
index 6676daf..0000000
--- a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler;
-
-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 FieldTest extends JavascriptTestBase {
-  use SchemaCheckTestTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_ui', 'views_test_config'];
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = ['test_field_body'];
-
-  /**
-   * The account.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $account;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    ViewTestData::createTestViews(get_class($this), ['views_test_config']);
-
-    // 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();
-  }
-
-  public function testFormatterChanging() {
-    $web_assert = $this->assertSession();
-    $url = '/admin/structure/views/view/test_field_body';
-    $this->drupalGet($url);
-
-    $page = $this->getSession()->getPage();
-
-    $page->clickLink('Body field');
-    $web_assert->assertWaitOnAjaxRequest();
-
-    $page->fillField('options[type]', 'text_trimmed');
-    // Add a value to the trim_length setting.
-    $web_assert->assertWaitOnAjaxRequest();
-    $page->fillField('options[settings][trim_length]', '700');
-    $apply_button = $page->find('css', '.views-ui-dialog button.button--primary');
-    $this->assertTrue(!empty($apply_button));
-    $apply_button->press();
-    $web_assert->assertWaitOnAjaxRequest();
-
-    // Save the page.
-    $save_button = $page->find('css', '#edit-actions-submit');
-    $save_button->press();
-
-    // Set the body field back to 'default' and test that the trim_length
-    // settings are not in the config.
-    $this->drupalGet($url);
-    $page->clickLink('Body field');
-    $web_assert->assertWaitOnAjaxRequest();
-
-    $page->fillField('options[type]', 'text_default');
-    $web_assert->assertWaitOnAjaxRequest();
-    $apply_button = $page->find('css', '.views-ui-dialog button.button--primary');
-    $apply_button->press();
-    $web_assert->assertWaitOnAjaxRequest();
-
-    // Save the page.
-    $save_button = $page->find('css', '#edit-actions-submit');
-    $save_button->press();
-
-    $this->assertConfigSchemaByName('views.view.test_field_body');
-  }
-
-}
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index fd031d2..c204ceb 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -193,7 +193,7 @@ function views_ui_ajax_update_form($form, FormStateInterface $form_state) {
 }
 
 /**
- * Non-Javascript fallback for updating the add view form.
+ * Non-JavaScript fallback for updating the add view form.
  */
 function views_ui_nojs_submit($form, FormStateInterface $form_state) {
   $form_state->setRebuild();
diff --git a/core/modules/views_ui/tests/src/FunctionalJavaScript/LibraryCachingTest.php b/core/modules/views_ui/tests/src/FunctionalJavaScript/LibraryCachingTest.php
new file mode 100644
index 0000000..42c69b6
--- /dev/null
+++ b/core/modules/views_ui/tests/src/FunctionalJavaScript/LibraryCachingTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Drupal\Tests\views_ui\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Tests the JavaScript library caching on consecutive requests.
+ *
+ * @group views_ui
+ */
+class LibraryCachingTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_ui'];
+
+  /**
+   * Tests if the Views UI dialogs open on consecutive requests.
+   */
+  public function testConsecutiveDialogRequests() {
+    $admin_user = $this->drupalCreateUser([
+      'administer site configuration',
+      'administer views',
+      'administer nodes',
+      'access content overview',
+    ]);
+
+    // Disable automatic live preview to make the sequence of calls clearer.
+    \Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save();
+    $this->drupalLogin($admin_user);
+
+    $this->drupalGet('admin/structure/views/view/content');
+    $page = $this->getSession()->getPage();
+
+    // Use the 'Add' link for fields to open a dialog. This will load the proper
+    // dialog libraries.
+    $add_link = $page->findById('views-add-field');
+    $this->assertTrue($add_link->isVisible(), 'Add fields button found.');
+    $add_link->click();
+    $this->getSession()->wait(5000, "jQuery('.ui-dialog-titlebar').length > 0");
+    // Close the dialog and open it again. No no libraries will be loaded, but a
+    // cache entry will be made for not loading any libraries.
+    $page->pressButton('Close');
+    $add_link->click();
+    $this->getSession()->wait(5000, "jQuery('.ui-dialog-titlebar').length > 0");
+    $page->pressButton('Close');
+
+    // Reload the page.
+    $this->drupalGet('admin/structure/views/view/content');
+    $page = $this->getSession()->getPage();
+
+    // Now use the 'Update preview' button to load libraries.
+    $preview = $page->findById('preview-submit');
+    // The first click will load all the libraries.
+    $preview->click();
+    $this->getSession()->wait(5000, "jQuery('.ajax-progress').length === 0");
+    // The second click will not load any new libraries.
+    $preview->click();
+    $this->getSession()->wait(5000, "jQuery('.ajax-progress').length === 0");
+    // Check to see if the dialogs still open.
+    $add_link = $page->findById('views-add-field');
+    $add_link->click();
+    $this->getSession()->wait(5000, "jQuery('.ui-dialog-titlebar').length > 0");
+    $page->pressButton('Close');
+  }
+
+}
diff --git a/core/modules/views_ui/tests/src/FunctionalJavaScript/ViewsListingTest.php b/core/modules/views_ui/tests/src/FunctionalJavaScript/ViewsListingTest.php
new file mode 100644
index 0000000..3797853
--- /dev/null
+++ b/core/modules/views_ui/tests/src/FunctionalJavaScript/ViewsListingTest.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Drupal\Tests\views_ui\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Tests the JavaScript filtering on the Views listing page.
+ *
+ * @see core/modules/views_ui/js/views_ui.listing.js
+ * @group views_ui
+ */
+class ViewsListingTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_ui'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $admin_user = $this->drupalCreateUser([
+      'administer site configuration',
+      'administer views',
+    ]);
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Tests the filtering on the Views listing page.
+   */
+  public function testFilterViewsListing() {
+    $this->drupalGet('admin/structure/views');
+
+    $session = $this->assertSession();
+
+    $page = $this->getSession()->getPage();
+
+    // Test that we search in both the enabled and disabled rows.
+    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
+    $enabled_rows = $this->filterVisibleElements($enabled_rows);
+    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
+    $disabled_rows = $this->filterVisibleElements($disabled_rows);
+
+    // Test that we see some rows of views in both tables.
+    $this->assertCount(6, $enabled_rows);
+    $this->assertCount(2, $disabled_rows);
+
+    // Filter on the string 'people'. This should only show the people view.
+    $search_input = $page->find('css', '.views-filter-text.form-search');
+    $search_input->setValue('people');
+
+    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
+    $enabled_rows = $this->filterVisibleElements($enabled_rows);
+    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
+    $disabled_rows = $this->filterVisibleElements($disabled_rows);
+
+    $this->assertCount(1, $enabled_rows);
+    $this->assertCount(0, $disabled_rows);
+
+    // Filter on a string that also appears in the description.
+    $search_input->setValue('content');
+
+    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
+    $enabled_rows = $this->filterVisibleElements($enabled_rows);
+    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
+    $disabled_rows = $this->filterVisibleElements($disabled_rows);
+
+    $this->assertCount(3, $enabled_rows);
+    $this->assertCount(2, $disabled_rows);
+
+    // Reset the search string and check that we are back to the initial stage.
+    $search_input->setValue('');
+    // Add a backspace to trigger the keyUp event.
+    $search_input->keyUp(8);
+
+    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
+    $enabled_rows = $this->filterVisibleElements($enabled_rows);
+    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
+    $disabled_rows = $this->filterVisibleElements($disabled_rows);
+
+    $this->assertCount(6, $enabled_rows);
+    $this->assertCount(2, $disabled_rows);
+
+    // Disable a View and see if it moves to the disabled listing.
+    $enabled_view = $page->find('css', 'tr.views-ui-list-enabled');
+    // Open the dropdown with additional actions.
+    $enabled_view->find('css', 'li.dropbutton-toggle button')->click();
+    $disable_button = $enabled_view->find('css', 'li.disable.dropbutton-action a');
+    // Check that the disable button is visible now.
+    $this->assertTrue($disable_button->isVisible());
+    $disable_button->click();
+
+    $session->assertWaitOnAjaxRequest();
+
+    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
+    $enabled_rows = $this->filterVisibleElements($enabled_rows);
+    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
+    $disabled_rows = $this->filterVisibleElements($disabled_rows);
+
+    // Test that one enabled View has been moved to the disabled list.
+    $this->assertCount(5, $enabled_rows);
+    $this->assertCount(3, $disabled_rows);
+  }
+
+  /**
+   * Removes any non-visible elements from the passed array.
+   *
+   * @param array $elements
+   * @return array
+   */
+  protected function filterVisibleElements($elements) {
+    $elements = array_filter($elements, function($element) {
+      return $element->isVisible();
+    });
+    return $elements;
+  }
+
+}
diff --git a/core/modules/views_ui/tests/src/FunctionalJavaScript/ViewsWizardTest.php b/core/modules/views_ui/tests/src/FunctionalJavaScript/ViewsWizardTest.php
new file mode 100644
index 0000000..3a7f714
--- /dev/null
+++ b/core/modules/views_ui/tests/src/FunctionalJavaScript/ViewsWizardTest.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Drupal\Tests\views_ui\FunctionalJavaScript;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Tests views creation wizard.
+ *
+ * @see core/modules/views_ui/js/views-admin.js
+ * @group views_ui
+ */
+class ViewsWizardTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views', 'views_ui', 'block'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $admin_user = $this->drupalCreateUser([
+      'administer site configuration',
+      'administer views',
+    ]);
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Tests creating a View using the wizard.
+   */
+  public function testCreateViewWizard() {
+    $this->drupalGet('admin/structure/views/add');
+    $page = $this->getSession()->getPage();
+
+    // Set a view name, this should be used to prepopulate a number of other
+    // fields when creating displays.
+    $label_value = 'test view';
+    $search_input = $page->findField('label');
+    $search_input->setValue($label_value);
+
+    $page->findField('page[create]')->click();
+
+    // Test if the title and path have been populated.
+    $this->assertEquals($label_value, $page->findField('page[title]')->getValue());
+    $this->assertEquals(str_replace(' ', '-', $label_value), $page->findField('page[path]')->getValue());
+
+    // Create a menu item.
+    $page->findField('page[link]')->click();
+    $this->assertEquals($label_value, $page->findField('page[link_properties][title]')->getValue());
+
+    // Add a block display.
+    $page->findField('block[create]')->click();
+    $this->assertEquals($label_value, $page->findField('block[title]')->getValue());
+  }
+
+}
diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/LibraryCachingTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/LibraryCachingTest.php
deleted file mode 100644
index fc98e87..0000000
--- a/core/modules/views_ui/tests/src/FunctionalJavascript/LibraryCachingTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views_ui\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests the JavaScript library caching on consecutive requests.
- *
- * @group views_ui
- */
-class LibraryCachingTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_ui'];
-
-  /**
-   * Tests if the Views UI dialogs open on consecutive requests.
-   */
-  public function testConsecutiveDialogRequests() {
-    $admin_user = $this->drupalCreateUser([
-      'administer site configuration',
-      'administer views',
-      'administer nodes',
-      'access content overview',
-    ]);
-
-    // Disable automatic live preview to make the sequence of calls clearer.
-    \Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save();
-    $this->drupalLogin($admin_user);
-
-    $this->drupalGet('admin/structure/views/view/content');
-    $page = $this->getSession()->getPage();
-
-    // Use the 'Add' link for fields to open a dialog. This will load the proper
-    // dialog libraries.
-    $add_link = $page->findById('views-add-field');
-    $this->assertTrue($add_link->isVisible(), 'Add fields button found.');
-    $add_link->click();
-    $this->getSession()->wait(5000, "jQuery('.ui-dialog-titlebar').length > 0");
-    // Close the dialog and open it again. No no libraries will be loaded, but a
-    // cache entry will be made for not loading any libraries.
-    $page->pressButton('Close');
-    $add_link->click();
-    $this->getSession()->wait(5000, "jQuery('.ui-dialog-titlebar').length > 0");
-    $page->pressButton('Close');
-
-    // Reload the page.
-    $this->drupalGet('admin/structure/views/view/content');
-    $page = $this->getSession()->getPage();
-
-    // Now use the 'Update preview' button to load libraries.
-    $preview = $page->findById('preview-submit');
-    // The first click will load all the libraries.
-    $preview->click();
-    $this->getSession()->wait(5000, "jQuery('.ajax-progress').length === 0");
-    // The second click will not load any new libraries.
-    $preview->click();
-    $this->getSession()->wait(5000, "jQuery('.ajax-progress').length === 0");
-    // Check to see if the dialogs still open.
-    $add_link = $page->findById('views-add-field');
-    $add_link->click();
-    $this->getSession()->wait(5000, "jQuery('.ui-dialog-titlebar').length > 0");
-    $page->pressButton('Close');
-  }
-
-}
diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php
deleted file mode 100644
index c39db77..0000000
--- a/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views_ui\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests the JavaScript filtering on the Views listing page.
- *
- * @see core/modules/views_ui/js/views_ui.listing.js
- * @group views_ui
- */
-class ViewsListingTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_ui'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $admin_user = $this->drupalCreateUser([
-      'administer site configuration',
-      'administer views',
-    ]);
-    $this->drupalLogin($admin_user);
-  }
-
-  /**
-   * Tests the filtering on the Views listing page.
-   */
-  public function testFilterViewsListing() {
-    $this->drupalGet('admin/structure/views');
-
-    $session = $this->assertSession();
-
-    $page = $this->getSession()->getPage();
-
-    // Test that we search in both the enabled and disabled rows.
-    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
-    $enabled_rows = $this->filterVisibleElements($enabled_rows);
-    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
-    $disabled_rows = $this->filterVisibleElements($disabled_rows);
-
-    // Test that we see some rows of views in both tables.
-    $this->assertCount(6, $enabled_rows);
-    $this->assertCount(2, $disabled_rows);
-
-    // Filter on the string 'people'. This should only show the people view.
-    $search_input = $page->find('css', '.views-filter-text.form-search');
-    $search_input->setValue('people');
-
-    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
-    $enabled_rows = $this->filterVisibleElements($enabled_rows);
-    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
-    $disabled_rows = $this->filterVisibleElements($disabled_rows);
-
-    $this->assertCount(1, $enabled_rows);
-    $this->assertCount(0, $disabled_rows);
-
-    // Filter on a string that also appears in the description.
-    $search_input->setValue('content');
-
-    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
-    $enabled_rows = $this->filterVisibleElements($enabled_rows);
-    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
-    $disabled_rows = $this->filterVisibleElements($disabled_rows);
-
-    $this->assertCount(3, $enabled_rows);
-    $this->assertCount(2, $disabled_rows);
-
-    // Reset the search string and check that we are back to the initial stage.
-    $search_input->setValue('');
-    // Add a backspace to trigger the keyUp event.
-    $search_input->keyUp(8);
-
-    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
-    $enabled_rows = $this->filterVisibleElements($enabled_rows);
-    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
-    $disabled_rows = $this->filterVisibleElements($disabled_rows);
-
-    $this->assertCount(6, $enabled_rows);
-    $this->assertCount(2, $disabled_rows);
-
-    // Disable a View and see if it moves to the disabled listing.
-    $enabled_view = $page->find('css', 'tr.views-ui-list-enabled');
-    // Open the dropdown with additional actions.
-    $enabled_view->find('css', 'li.dropbutton-toggle button')->click();
-    $disable_button = $enabled_view->find('css', 'li.disable.dropbutton-action a');
-    // Check that the disable button is visible now.
-    $this->assertTrue($disable_button->isVisible());
-    $disable_button->click();
-
-    $session->assertWaitOnAjaxRequest();
-
-    $enabled_rows = $page->findAll('css', 'tr.views-ui-list-enabled');
-    $enabled_rows = $this->filterVisibleElements($enabled_rows);
-    $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled');
-    $disabled_rows = $this->filterVisibleElements($disabled_rows);
-
-    // Test that one enabled View has been moved to the disabled list.
-    $this->assertCount(5, $enabled_rows);
-    $this->assertCount(3, $disabled_rows);
-  }
-
-  /**
-   * Removes any non-visible elements from the passed array.
-   *
-   * @param array $elements
-   * @return array
-   */
-  protected function filterVisibleElements($elements) {
-    $elements = array_filter($elements, function($element) {
-      return $element->isVisible();
-    });
-    return $elements;
-  }
-
-}
diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsWizardTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsWizardTest.php
deleted file mode 100644
index 6320f69..0000000
--- a/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsWizardTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-namespace Drupal\Tests\views_ui\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests views creation wizard.
- *
- * @see core/modules/views_ui/js/views-admin.js
- * @group views_ui
- */
-class ViewsWizardTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node', 'views', 'views_ui', 'block'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $admin_user = $this->drupalCreateUser([
-      'administer site configuration',
-      'administer views',
-    ]);
-    $this->drupalLogin($admin_user);
-  }
-
-  /**
-   * Tests creating a View using the wizard.
-   */
-  public function testCreateViewWizard() {
-    $this->drupalGet('admin/structure/views/add');
-    $page = $this->getSession()->getPage();
-
-    // Set a view name, this should be used to prepopulate a number of other
-    // fields when creating displays.
-    $label_value = 'test view';
-    $search_input = $page->findField('label');
-    $search_input->setValue($label_value);
-
-    $page->findField('page[create]')->click();
-
-    // Test if the title and path have been populated.
-    $this->assertEquals($label_value, $page->findField('page[title]')->getValue());
-    $this->assertEquals(str_replace(' ', '-', $label_value), $page->findField('page[path]')->getValue());
-
-    // Create a menu item.
-    $page->findField('page[link]')->click();
-    $this->assertEquals($label_value, $page->findField('page[link_properties][title]')->getValue());
-
-    // Add a block display.
-    $page->findField('block[create]')->click();
-    $this->assertEquals($label_value, $page->findField('block[title]')->getValue());
-  }
-
-}
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index 9658f2c..0a31c84 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -41,7 +41,7 @@
       <file>./tests/TestSuites/FunctionalTestSuite.php</file>
     </testsuite>
     <testsuite name="functional-javascript">
-      <file>./tests/TestSuites/FunctionalJavascriptTestSuite.php</file>
+      <file>./tests/TestSuites/FunctionalJavaScriptTestSuite.php</file>
     </testsuite>
   </testsuites>
   <listeners>
diff --git a/core/tests/Drupal/FunctionalJavaScriptTests/Ajax/AjaxTest.php b/core/tests/Drupal/FunctionalJavaScriptTests/Ajax/AjaxTest.php
new file mode 100644
index 0000000..4f87b8d
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavaScriptTests/Ajax/AjaxTest.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Drupal\FunctionalJavaScriptTests\Ajax;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+
+/**
+ * Tests AJAX responses.
+ *
+ * @group Ajax
+ */
+class AjaxTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['ajax_test'];
+
+  public function testAjaxWithAdminRoute() {
+    \Drupal::service('theme_installer')->install(['stable', 'seven']);
+    $theme_config = \Drupal::configFactory()->getEditable('system.theme');
+    $theme_config->set('admin', 'seven');
+    $theme_config->set('default', 'stable');
+    $theme_config->save();
+
+    $account = $this->drupalCreateUser(['view the administration theme']);
+    $this->drupalLogin($account);
+
+    // First visit the site directly via the URL. This should render it in the
+    // admin theme.
+    $this->drupalGet('admin/ajax-test/theme');
+    $assert = $this->assertSession();
+    $assert->pageTextContains('Current theme: seven');
+
+    // Now click the modal, which should also use the admin theme.
+    $this->drupalGet('ajax-test/dialog');
+    $assert->pageTextNotContains('Current theme: stable');
+    $this->clickLink('Link 8 (ajax)');
+    $assert->assertWaitOnAjaxRequest();
+
+    $assert->pageTextContains('Current theme: stable');
+    $assert->pageTextNotContains('Current theme: seven');
+  }
+
+  /**
+   * Test that AJAX loaded libraries are not retained between requests.
+   *
+   * @see https://www.drupal.org/node/2647916
+   */
+  public function testDrupalSettingsCachingRegression() {
+    $this->drupalGet('ajax-test/dialog');
+    $assert = $this->assertSession();
+    $session = $this->getSession();
+
+    // Insert a fake library into the already loaded library settings.
+    $fake_library = 'fakeLibrary/fakeLibrary';
+    $session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';");
+
+    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
+    // Test that the fake library is set.
+    $this->assertContains($fake_library, $libraries);
+
+    // Click on the AJAX link.
+    $this->clickLink('Link 8 (ajax)');
+    $assert->assertWaitOnAjaxRequest();
+
+    // Test that the fake library is still set after the AJAX call.
+    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
+    $this->assertContains($fake_library, $libraries);
+
+    // Reload the page, this should reset the loaded libraries and remove the
+    // fake library.
+    $this->drupalGet('ajax-test/dialog');
+    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
+    $this->assertNotContains($fake_library, $libraries);
+
+    // Click on the AJAX link again, and the libraries should still not contain
+    // the fake library.
+    $this->clickLink('Link 8 (ajax)');
+    $assert->assertWaitOnAjaxRequest();
+    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
+    $this->assertNotContains($fake_library, $libraries);
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavaScriptTests/Core/Session/SessionTest.php b/core/tests/Drupal/FunctionalJavaScriptTests/Core/Session/SessionTest.php
new file mode 100644
index 0000000..528bb18
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavaScriptTests/Core/Session/SessionTest.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Drupal\FunctionalJavaScriptTests\Core\Session;
+
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\menu_link_content\Entity\MenuLinkContent;
+
+/**
+ * Tests that sessions don't expire.
+ *
+ * @group session
+ */
+class SessionTest extends JavaScriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['menu_link_content', 'block'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $account = $this->drupalCreateUser();
+    $this->drupalLogin($account);
+
+    $menu_link_content = MenuLinkContent::create([
+      'title' => 'Link to front page',
+      'menu_name' => 'tools',
+      'link' => ['uri' => 'route:<front>'],
+    ]);
+    $menu_link_content->save();
+
+    $this->drupalPlaceBlock('system_menu_block:tools');
+  }
+
+  /**
+   * Tests that the session doesn't expire.
+   *
+   * Makes sure that drupal_valid_test_ua() works for multiple requests
+   * performed by the Mink browser. The SIMPLETEST_USER_AGENT cookie must always
+   * be valid.
+   */
+  public function testSessionExpiration() {
+    // Visit the front page and click the link back to the front page a large
+    // number of times.
+    $this->drupalGet('<front>');
+
+    $session_assert = $this->assertSession();
+
+    $page = $this->getSession()->getPage();
+
+    for ($i = 0; $i < 25; $i++) {
+      $page->clickLink('Link to front page');
+      $session_assert->statusCodeEquals(200);
+    }
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavaScriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php b/core/tests/Drupal/FunctionalJavaScriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
new file mode 100644
index 0000000..f3d4b44
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavaScriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
@@ -0,0 +1,102 @@
+<?php
+
+namespace Drupal\FunctionalJavaScriptTests\EntityReference;
+
+use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
+use Drupal\FunctionalJavaScriptTests\JavaScriptTestBase;
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\simpletest\NodeCreationTrait;
+
+/**
+ * Tests the output of entity reference autocomplete widgets.
+ *
+ * @group entity_reference
+ */
+class EntityReferenceAutocompleteWidgetTest extends JavaScriptTestBase {
+
+  use ContentTypeCreationTrait;
+  use EntityReferenceTestTrait;
+  use NodeCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create a Content type and two test nodes.
+    $this->createContentType(['type' => 'page']);
+    $this->createNode(['title' => 'Test page']);
+    $this->createNode(['title' => 'Page test']);
+
+    $user = $this->drupalCreateUser([
+      'access content',
+      'create page content',
+    ]);
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Tests that the default autocomplete widget return the correct results.
+   */
+  public function testEntityReferenceAutocompleteWidget() {
+    // Create an entity reference field and use the default 'CONTAINS' match
+    // operator.
+    $field_name = 'field_test';
+    $this->createEntityReferenceField('node', 'page', $field_name, $field_name, 'node', 'default', ['target_bundles' => ['page']]);
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($field_name, [
+        'type' => 'entity_reference_autocomplete',
+        'settings' => array(
+          'match_operator' => 'CONTAINS',
+        ),
+      ])
+      ->save();
+
+    // Visit the node add page.
+    $this->drupalGet('node/add/page');
+    $page = $this->getSession()->getPage();
+    $assert_session = $this->assertSession();
+
+    $autocomplete_field = $page->findField($field_name . '[0][target_id]');
+    $autocomplete_field->setValue('Test');
+    $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
+    $assert_session->waitOnAutocomplete();
+
+    $results = $page->findAll('css', '.ui-autocomplete li');
+
+    $this->assertCount(2, $results);
+    $assert_session->pageTextContains('Test page');
+    $assert_session->pageTextContains('Page test');
+
+    // Now switch the autocomplete widget to the 'STARTS_WITH' match operator.
+    entity_get_form_display('node', 'page', 'default')
+      ->setComponent($field_name, [
+        'type' => 'entity_reference_autocomplete',
+        'settings' => array(
+          'match_operator' => 'STARTS_WITH',
+        ),
+      ])
+      ->save();
+
+    $this->drupalGet('node/add/page');
+    $page = $this->getSession()->getPage();
+
+    $autocomplete_field = $page->findField($field_name . '[0][target_id]');
+    $autocomplete_field->setValue('Test');
+    $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
+    $assert_session->waitOnAutocomplete();
+
+    $results = $page->findAll('css', '.ui-autocomplete li');
+
+    $this->assertCount(1, $results);
+    $assert_session->pageTextContains('Test page');
+    $assert_session->pageTextNotContains('Page test');
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavaScriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavaScriptTests/JSWebAssert.php
new file mode 100644
index 0000000..ed809c6
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavaScriptTests/JSWebAssert.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\FunctionalJavaScriptTests;
+
+use Drupal\Tests\WebAssert;
+
+/**
+ * Defines a class with methods for asserting presence of elements during tests.
+ */
+class JSWebAssert extends WebAssert {
+
+  /**
+   * Waits for AJAX request to be completed.
+   *
+   * @param int $timeout
+   *   (Optional) Timeout in milliseconds, defaults to 10000.
+   * @param string $message
+   *   (optional) A message for exception.
+   *
+   * @throws \RuntimeException
+   *   When the request is not completed. If left blank, a default message will
+   *   be displayed.
+   */
+  public function assertWaitOnAjaxRequest($timeout = 10000, $message = 'Unable to complete AJAX request.') {
+    $result = $this->session->wait($timeout, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
+    if (!$result) {
+      throw new \RuntimeException($message);
+    }
+  }
+
+  /**
+   * Waits for the jQuery autocomplete delay duration.
+   *
+   * @see https://api.jqueryui.com/autocomplete/#option-delay
+   */
+  public function waitOnAutocomplete() {
+    // Drupal is using the default delay value of 300 milliseconds.
+    $this->session->wait(300);
+    $this->assertWaitOnAjaxRequest();
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavaScriptTests/JavaScriptTestBase.php b/core/tests/Drupal/FunctionalJavaScriptTests/JavaScriptTestBase.php
new file mode 100644
index 0000000..508d964
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavaScriptTests/JavaScriptTestBase.php
@@ -0,0 +1,146 @@
+<?php
+
+namespace Drupal\FunctionalJavaScriptTests;
+
+use Drupal\Tests\BrowserTestBase;
+use Zumba\GastonJS\Exception\DeadClient;
+use Zumba\Mink\Driver\PhantomJSDriver;
+
+/**
+ * Runs a browser test using PhantomJS.
+ *
+ * Base class for testing browser interaction implemented in JavaScript.
+ */
+abstract class JavaScriptTestBase extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $minkDefaultDriverClass = PhantomJSDriver::class;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function initMink() {
+    // Set up the template cache used by the PhantomJS mink driver.
+    $path = $this->tempFilesDirectory . DIRECTORY_SEPARATOR . 'browsertestbase-templatecache';
+    $this->minkDefaultDriverArgs = [
+      'http://127.0.0.1:8510',
+      $path,
+    ];
+    if (!file_exists($path)) {
+      mkdir($path);
+    }
+
+    try {
+      return parent::initMink();
+    }
+    catch (DeadClient $e) {
+      $this->markTestSkipped('PhantomJS is either not installed or not running. Start it via phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768&');
+    }
+    catch (\Exception $e) {
+      $this->markTestSkipped('An unexpected error occurred while starting Mink: ' . $e->getMessage());
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function tearDown() {
+    // Wait for all requests to finish. It is possible that an AJAX request is
+    // still on-going.
+    $result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
+    if (!$result) {
+      // If the wait is unsuccessful, there may still be an AJAX request in
+      // progress. If we tear down now, then this AJAX request may fail with
+      // missing database tables, because tear down will have removed them. Rather
+      // than allow it to fail, throw an explicit exception now explaining what
+      // the problem is.
+      throw new \RuntimeException('Unfinished AJAX requests whilst tearing down a test');
+    }
+    parent::tearDown();
+  }
+
+  /**
+   * Asserts that the element with the given CSS selector is visible.
+   *
+   * @param string $css_selector
+   *   The CSS selector identifying the element to check.
+   * @param string $message
+   *   Optional message to show alongside the assertion.
+   *
+   * @deprecated in Drupal 8.1.x, will be removed before Drupal 8.3.x. Use
+   *   \Behat\Mink\Element\NodeElement::isVisible() instead.
+   */
+  protected function assertElementVisible($css_selector, $message = '') {
+    $this->assertTrue($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
+  }
+
+  /**
+   * Asserts that the element with the given CSS selector is not visible.
+   *
+   * @param string $css_selector
+   *   The CSS selector identifying the element to check.
+   * @param string $message
+   *   Optional message to show alongside the assertion.
+   *
+   * @deprecated in Drupal 8.1.x, will be removed before Drupal 8.3.x. Use
+   *   \Behat\Mink\Element\NodeElement::isVisible() instead.
+   */
+  protected function assertElementNotVisible($css_selector, $message = '') {
+    $this->assertFalse($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
+  }
+
+  /**
+   * Waits for the given time or until the given JS condition becomes TRUE.
+   *
+   * @param string $condition
+   *   JS condition to wait until it becomes TRUE.
+   * @param int $timeout
+   *   (Optional) Timeout in milliseconds, defaults to 1000.
+   * @param string $message
+   *   (optional) A message to display with the assertion. If left blank, a
+   *   default message will be displayed.
+   *
+   * @throws \PHPUnit_Framework_AssertionFailedError
+   *
+   * @see \Behat\Mink\Driver\DriverInterface::evaluateScript()
+   */
+  protected function assertJsCondition($condition, $timeout = 1000, $message = '') {
+    $message = $message ?: "JavaScript condition met:\n" . $condition;
+    $result = $this->getSession()->getDriver()->wait($timeout, $condition);
+    $this->assertTrue($result, $message);
+  }
+
+  /**
+   * Creates a screenshot.
+   *
+   * @param string $filename
+   *   The file name of the resulting screenshot. If using the default phantomjs
+   *   driver then this should be a JPG filename.
+   * @param bool $set_background_color
+   *   (optional) By default this method will set the background color to white.
+   *   Set to FALSE to override this behaviour.
+   *
+   * @throws \Behat\Mink\Exception\UnsupportedDriverActionException
+   *   When operation not supported by the driver.
+   * @throws \Behat\Mink\Exception\DriverException
+   *   When the operation cannot be done.
+   */
+  protected function createScreenshot($filename, $set_background_color = TRUE) {
+    $session = $this->getSession();
+    if ($set_background_color) {
+      $session->executeScript("document.body.style.backgroundColor = 'white';");
+    }
+    $image = $session->getScreenshot();
+    file_put_contents($filename, $image);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function assertSession($name = NULL) {
+    return new JSWebAssert($this->getSession($name), $this->baseUrl);
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php
deleted file mode 100644
index e059405..0000000
--- a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php
-
-namespace Drupal\FunctionalJavascriptTests\Ajax;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests AJAX responses.
- *
- * @group Ajax
- */
-class AjaxTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['ajax_test'];
-
-  public function testAjaxWithAdminRoute() {
-    \Drupal::service('theme_installer')->install(['stable', 'seven']);
-    $theme_config = \Drupal::configFactory()->getEditable('system.theme');
-    $theme_config->set('admin', 'seven');
-    $theme_config->set('default', 'stable');
-    $theme_config->save();
-
-    $account = $this->drupalCreateUser(['view the administration theme']);
-    $this->drupalLogin($account);
-
-    // First visit the site directly via the URL. This should render it in the
-    // admin theme.
-    $this->drupalGet('admin/ajax-test/theme');
-    $assert = $this->assertSession();
-    $assert->pageTextContains('Current theme: seven');
-
-    // Now click the modal, which should also use the admin theme.
-    $this->drupalGet('ajax-test/dialog');
-    $assert->pageTextNotContains('Current theme: stable');
-    $this->clickLink('Link 8 (ajax)');
-    $assert->assertWaitOnAjaxRequest();
-
-    $assert->pageTextContains('Current theme: stable');
-    $assert->pageTextNotContains('Current theme: seven');
-  }
-
-  /**
-   * Test that AJAX loaded libraries are not retained between requests.
-   *
-   * @see https://www.drupal.org/node/2647916
-   */
-  public function testDrupalSettingsCachingRegression() {
-    $this->drupalGet('ajax-test/dialog');
-    $assert = $this->assertSession();
-    $session = $this->getSession();
-
-    // Insert a fake library into the already loaded library settings.
-    $fake_library = 'fakeLibrary/fakeLibrary';
-    $session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';");
-
-    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
-    // Test that the fake library is set.
-    $this->assertContains($fake_library, $libraries);
-
-    // Click on the AJAX link.
-    $this->clickLink('Link 8 (ajax)');
-    $assert->assertWaitOnAjaxRequest();
-
-    // Test that the fake library is still set after the AJAX call.
-    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
-    $this->assertContains($fake_library, $libraries);
-
-    // Reload the page, this should reset the loaded libraries and remove the
-    // fake library.
-    $this->drupalGet('ajax-test/dialog');
-    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
-    $this->assertNotContains($fake_library, $libraries);
-
-    // Click on the AJAX link again, and the libraries should still not contain
-    // the fake library.
-    $this->clickLink('Link 8 (ajax)');
-    $assert->assertWaitOnAjaxRequest();
-    $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
-    $this->assertNotContains($fake_library, $libraries);
-  }
-
-}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php
deleted file mode 100644
index e02e0df..0000000
--- a/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-namespace Drupal\FunctionalJavascriptTests\Core\Session;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\menu_link_content\Entity\MenuLinkContent;
-
-/**
- * Tests that sessions don't expire.
- *
- * @group session
- */
-class SessionTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['menu_link_content', 'block'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $account = $this->drupalCreateUser();
-    $this->drupalLogin($account);
-
-    $menu_link_content = MenuLinkContent::create([
-      'title' => 'Link to front page',
-      'menu_name' => 'tools',
-      'link' => ['uri' => 'route:<front>'],
-    ]);
-    $menu_link_content->save();
-
-    $this->drupalPlaceBlock('system_menu_block:tools');
-  }
-
-  /**
-   * Tests that the session doesn't expire.
-   *
-   * Makes sure that drupal_valid_test_ua() works for multiple requests
-   * performed by the Mink browser. The SIMPLETEST_USER_AGENT cookie must always
-   * be valid.
-   */
-  public function testSessionExpiration() {
-    // Visit the front page and click the link back to the front page a large
-    // number of times.
-    $this->drupalGet('<front>');
-
-    $session_assert = $this->assertSession();
-
-    $page = $this->getSession()->getPage();
-
-    for ($i = 0; $i < 25; $i++) {
-      $page->clickLink('Link to front page');
-      $session_assert->statusCodeEquals(200);
-    }
-  }
-
-}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
deleted file mode 100644
index a116c6f..0000000
--- a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-namespace Drupal\FunctionalJavascriptTests\EntityReference;
-
-use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\simpletest\ContentTypeCreationTrait;
-use Drupal\simpletest\NodeCreationTrait;
-
-/**
- * Tests the output of entity reference autocomplete widgets.
- *
- * @group entity_reference
- */
-class EntityReferenceAutocompleteWidgetTest extends JavascriptTestBase {
-
-  use ContentTypeCreationTrait;
-  use EntityReferenceTestTrait;
-  use NodeCreationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['node'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    // Create a Content type and two test nodes.
-    $this->createContentType(['type' => 'page']);
-    $this->createNode(['title' => 'Test page']);
-    $this->createNode(['title' => 'Page test']);
-
-    $user = $this->drupalCreateUser([
-      'access content',
-      'create page content',
-    ]);
-    $this->drupalLogin($user);
-  }
-
-  /**
-   * Tests that the default autocomplete widget return the correct results.
-   */
-  public function testEntityReferenceAutocompleteWidget() {
-    // Create an entity reference field and use the default 'CONTAINS' match
-    // operator.
-    $field_name = 'field_test';
-    $this->createEntityReferenceField('node', 'page', $field_name, $field_name, 'node', 'default', ['target_bundles' => ['page']]);
-    entity_get_form_display('node', 'page', 'default')
-      ->setComponent($field_name, [
-        'type' => 'entity_reference_autocomplete',
-        'settings' => array(
-          'match_operator' => 'CONTAINS',
-        ),
-      ])
-      ->save();
-
-    // Visit the node add page.
-    $this->drupalGet('node/add/page');
-    $page = $this->getSession()->getPage();
-    $assert_session = $this->assertSession();
-
-    $autocomplete_field = $page->findField($field_name . '[0][target_id]');
-    $autocomplete_field->setValue('Test');
-    $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
-    $assert_session->waitOnAutocomplete();
-
-    $results = $page->findAll('css', '.ui-autocomplete li');
-
-    $this->assertCount(2, $results);
-    $assert_session->pageTextContains('Test page');
-    $assert_session->pageTextContains('Page test');
-
-    // Now switch the autocomplete widget to the 'STARTS_WITH' match operator.
-    entity_get_form_display('node', 'page', 'default')
-      ->setComponent($field_name, [
-        'type' => 'entity_reference_autocomplete',
-        'settings' => array(
-          'match_operator' => 'STARTS_WITH',
-        ),
-      ])
-      ->save();
-
-    $this->drupalGet('node/add/page');
-    $page = $this->getSession()->getPage();
-
-    $autocomplete_field = $page->findField($field_name . '[0][target_id]');
-    $autocomplete_field->setValue('Test');
-    $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
-    $assert_session->waitOnAutocomplete();
-
-    $results = $page->findAll('css', '.ui-autocomplete li');
-
-    $this->assertCount(1, $results);
-    $assert_session->pageTextContains('Test page');
-    $assert_session->pageTextNotContains('Page test');
-  }
-
-}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
deleted file mode 100644
index 46f6017..0000000
--- a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-namespace Drupal\FunctionalJavascriptTests;
-
-use Drupal\Tests\WebAssert;
-
-/**
- * Defines a class with methods for asserting presence of elements during tests.
- */
-class JSWebAssert extends WebAssert {
-
-  /**
-   * Waits for AJAX request to be completed.
-   *
-   * @param int $timeout
-   *   (Optional) Timeout in milliseconds, defaults to 10000.
-   * @param string $message
-   *   (optional) A message for exception.
-   *
-   * @throws \RuntimeException
-   *   When the request is not completed. If left blank, a default message will
-   *   be displayed.
-   */
-  public function assertWaitOnAjaxRequest($timeout = 10000, $message = 'Unable to complete AJAX request.') {
-    $result = $this->session->wait($timeout, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
-    if (!$result) {
-      throw new \RuntimeException($message);
-    }
-  }
-
-  /**
-   * Waits for the jQuery autocomplete delay duration.
-   *
-   * @see https://api.jqueryui.com/autocomplete/#option-delay
-   */
-  public function waitOnAutocomplete() {
-    // Drupal is using the default delay value of 300 milliseconds.
-    $this->session->wait(300);
-    $this->assertWaitOnAjaxRequest();
-  }
-
-}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php
deleted file mode 100644
index 092d0cd..0000000
--- a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-
-namespace Drupal\FunctionalJavascriptTests;
-
-use Drupal\Tests\BrowserTestBase;
-use Zumba\GastonJS\Exception\DeadClient;
-use Zumba\Mink\Driver\PhantomJSDriver;
-
-/**
- * Runs a browser test using PhantomJS.
- *
- * Base class for testing browser interaction implemented in JavaScript.
- */
-abstract class JavascriptTestBase extends BrowserTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $minkDefaultDriverClass = PhantomJSDriver::class;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function initMink() {
-    // Set up the template cache used by the PhantomJS mink driver.
-    $path = $this->tempFilesDirectory . DIRECTORY_SEPARATOR . 'browsertestbase-templatecache';
-    $this->minkDefaultDriverArgs = [
-      'http://127.0.0.1:8510',
-      $path,
-    ];
-    if (!file_exists($path)) {
-      mkdir($path);
-    }
-
-    try {
-      return parent::initMink();
-    }
-    catch (DeadClient $e) {
-      $this->markTestSkipped('PhantomJS is either not installed or not running. Start it via phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768&');
-    }
-    catch (\Exception $e) {
-      $this->markTestSkipped('An unexpected error occurred while starting Mink: ' . $e->getMessage());
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function tearDown() {
-    // Wait for all requests to finish. It is possible that an AJAX request is
-    // still on-going.
-    $result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
-    if (!$result) {
-      // If the wait is unsuccessful, there may still be an AJAX request in
-      // progress. If we tear down now, then this AJAX request may fail with
-      // missing database tables, because tear down will have removed them. Rather
-      // than allow it to fail, throw an explicit exception now explaining what
-      // the problem is.
-      throw new \RuntimeException('Unfinished AJAX requests whilst tearing down a test');
-    }
-    parent::tearDown();
-  }
-
-  /**
-   * Asserts that the element with the given CSS selector is visible.
-   *
-   * @param string $css_selector
-   *   The CSS selector identifying the element to check.
-   * @param string $message
-   *   Optional message to show alongside the assertion.
-   *
-   * @deprecated in Drupal 8.1.x, will be removed before Drupal 8.3.x. Use
-   *   \Behat\Mink\Element\NodeElement::isVisible() instead.
-   */
-  protected function assertElementVisible($css_selector, $message = '') {
-    $this->assertTrue($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
-  }
-
-  /**
-   * Asserts that the element with the given CSS selector is not visible.
-   *
-   * @param string $css_selector
-   *   The CSS selector identifying the element to check.
-   * @param string $message
-   *   Optional message to show alongside the assertion.
-   *
-   * @deprecated in Drupal 8.1.x, will be removed before Drupal 8.3.x. Use
-   *   \Behat\Mink\Element\NodeElement::isVisible() instead.
-   */
-  protected function assertElementNotVisible($css_selector, $message = '') {
-    $this->assertFalse($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
-  }
-
-  /**
-   * Waits for the given time or until the given JS condition becomes TRUE.
-   *
-   * @param string $condition
-   *   JS condition to wait until it becomes TRUE.
-   * @param int $timeout
-   *   (Optional) Timeout in milliseconds, defaults to 1000.
-   * @param string $message
-   *   (optional) A message to display with the assertion. If left blank, a
-   *   default message will be displayed.
-   *
-   * @throws \PHPUnit_Framework_AssertionFailedError
-   *
-   * @see \Behat\Mink\Driver\DriverInterface::evaluateScript()
-   */
-  protected function assertJsCondition($condition, $timeout = 1000, $message = '') {
-    $message = $message ?: "Javascript condition met:\n" . $condition;
-    $result = $this->getSession()->getDriver()->wait($timeout, $condition);
-    $this->assertTrue($result, $message);
-  }
-
-  /**
-   * Creates a screenshot.
-   *
-   * @param string $filename
-   *   The file name of the resulting screenshot. If using the default phantomjs
-   *   driver then this should be a JPG filename.
-   * @param bool $set_background_color
-   *   (optional) By default this method will set the background color to white.
-   *   Set to FALSE to override this behaviour.
-   *
-   * @throws \Behat\Mink\Exception\UnsupportedDriverActionException
-   *   When operation not supported by the driver.
-   * @throws \Behat\Mink\Exception\DriverException
-   *   When the operation cannot be done.
-   */
-  protected function createScreenshot($filename, $set_background_color = TRUE) {
-    $session = $this->getSession();
-    if ($set_background_color) {
-      $session->executeScript("document.body.style.backgroundColor = 'white';");
-    }
-    $image = $session->getScreenshot();
-    file_put_contents($filename, $image);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function assertSession($name = NULL) {
-    return new JSWebAssert($this->getSession($name), $this->baseUrl);
-  }
-
-}
diff --git a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
index 2393f61..d8fd1c5 100644
--- a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
+++ b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
@@ -127,7 +127,7 @@ protected function assertTextHelper($text, $not_exists = TRUE) {
 
     $raw_content = $this->getSession()->getPage()->getContent();
     // Trying to simulate what the user sees, given that it removes all text
-    // inside the head tags, removes inline Javascript, fix all HTML entities,
+    // inside the head tags, removes inline JavaScript, fix all HTML entities,
     // removes dangerous protocols and filtering out all HTML tags, as they are
     // not visible in a normal browser.
     $raw_content = preg_replace('@<head>(.+?)</head>@si', '', $raw_content);
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 74a0635..9a19fca 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -731,7 +731,7 @@ protected function drupalGet($path, array $options = array(), array $headers = a
     // Ensure that any changes to variables in the other thread are picked up.
     $this->refreshVariables();
 
-    // Log only for JavascriptTestBase tests because for Goutte we log with
+    // Log only for JavaScriptTestBase tests because for Goutte we log with
     // ::getResponseLogHandler.
     if ($this->htmlOutputEnabled && !($this->getSession()->getDriver() instanceof GoutteDriver)) {
       $html_output = 'GET request to: ' . $url .
@@ -904,7 +904,7 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) {
     // Ensure that any changes to variables in the other thread are picked up.
     $this->refreshVariables();
 
-    // Log only for JavascriptTestBase tests because for Goutte we log with
+    // Log only for JavaScriptTestBase tests because for Goutte we log with
     // ::getResponseLogHandler.
     if ($this->htmlOutputEnabled && !($this->getSession()->getDriver() instanceof GoutteDriver)) {
       $out = $this->getSession()->getPage()->getContent();
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
index b945b14..6203a2f 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
@@ -262,7 +262,7 @@ public function providerTestSanitizeDestination() {
     $data[] = ['example:test', 'example:test'];
     // External URL is not allowed.
     $data[] = ['http://example.com', ''];
-    // Javascript URL is allowed because it is treated as an internal URL.
+    // JavaScript URL is allowed because it is treated as an internal URL.
     $data[] = ['javascript:alert(0)', 'javascript:alert(0)'];
 
     return $data;
diff --git a/core/tests/TestSuites/FunctionalJavaScriptTestSuite.php b/core/tests/TestSuites/FunctionalJavaScriptTestSuite.php
new file mode 100644
index 0000000..1c0dbe7
--- /dev/null
+++ b/core/tests/TestSuites/FunctionalJavaScriptTestSuite.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Tests\TestSuites;
+
+require_once __DIR__ . '/TestSuiteBase.php';
+
+/**
+ * Discovers tests for the functional-javascript test suite.
+ */
+class FunctionalJavaScriptTestSuite extends TestSuiteBase {
+
+  /**
+   * Factory method which loads up a suite with all functional javascript tests.
+   *
+   * @return static
+   *   The test suite.
+   */
+  public static function suite() {
+    $root = dirname(dirname(dirname(__DIR__)));
+
+    $suite = new static('functional-javascript');
+    $suite->addTestsBySuiteNamespace($root, 'FunctionalJavaScript');
+
+    return $suite;
+  }
+
+}
diff --git a/core/tests/TestSuites/FunctionalJavascriptTestSuite.php b/core/tests/TestSuites/FunctionalJavascriptTestSuite.php
deleted file mode 100644
index 626be02..0000000
--- a/core/tests/TestSuites/FunctionalJavascriptTestSuite.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-namespace Drupal\Tests\TestSuites;
-
-require_once __DIR__ . '/TestSuiteBase.php';
-
-/**
- * Discovers tests for the functional-javascript test suite.
- */
-class FunctionalJavascriptTestSuite extends TestSuiteBase {
-
-  /**
-   * Factory method which loads up a suite with all functional javascript tests.
-   *
-   * @return static
-   *   The test suite.
-   */
-  public static function suite() {
-    $root = dirname(dirname(dirname(__DIR__)));
-
-    $suite = new static('functional-javascript');
-    $suite->addTestsBySuiteNamespace($root, 'FunctionalJavascript');
-
-    return $suite;
-  }
-
-}
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index 9aeb1d7..8ac17d2 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -116,7 +116,7 @@ function drupal_phpunit_populate_class_loader() {
   $loader->add('Drupal\\Tests', __DIR__);
   $loader->add('Drupal\\KernelTests', __DIR__);
   $loader->add('Drupal\\FunctionalTests', __DIR__);
-  $loader->add('Drupal\\FunctionalJavascriptTests', __DIR__);
+  $loader->add('Drupal\\FunctionalJavaScriptTests', __DIR__);
 
   if (!isset($GLOBALS['namespaces'])) {
     // Scan for arbitrary extension namespaces from core and contrib.
diff --git a/core/themes/classy/templates/views/views-view.html.twig b/core/themes/classy/templates/views/views-view.html.twig
index f0ed63c..20484fb 100644
--- a/core/themes/classy/templates/views/views-view.html.twig
+++ b/core/themes/classy/templates/views/views-view.html.twig
@@ -25,7 +25,7 @@
  * - attachment_after: An optional attachment view to be displayed after the
  *   view content.
  * - dom_id: Unique id for every view being printed to give unique class for
- *   Javascript.
+ *   JavaScript.
  *
  * @see template_preprocess_views_view()
  */
diff --git a/core/themes/stable/css/system/components/js.module.css b/core/themes/stable/css/system/components/js.module.css
index f827020..f6c1c01 100644
--- a/core/themes/stable/css/system/components/js.module.css
+++ b/core/themes/stable/css/system/components/js.module.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Utility classes to assist with Javascript functionality.
+ * Utility classes to assist with JavaScript functionality.
  */
 
 /**
diff --git a/core/themes/stable/templates/views/views-view.html.twig b/core/themes/stable/templates/views/views-view.html.twig
index 5d372d7..d7c1486 100644
--- a/core/themes/stable/templates/views/views-view.html.twig
+++ b/core/themes/stable/templates/views/views-view.html.twig
@@ -25,7 +25,7 @@
  * - attachment_after: An optional attachment view to be displayed after the
  *   view content.
  * - dom_id: Unique id for every view being printed to give unique class for
- *   Javascript.
+ *   JavaScript.
  *
  * @see template_preprocess_views_view()
  */
