diff --git a/core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php b/core/modules/config/tests/src/Functional/CacheabilityMetadataConfigOverrideIntegrationTest.php
similarity index 89%
rename from core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php
rename to core/modules/config/tests/src/Functional/CacheabilityMetadataConfigOverrideIntegrationTest.php
index 3ef0754..f2f8730 100644
--- a/core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php
+++ b/core/modules/config/tests/src/Functional/CacheabilityMetadataConfigOverrideIntegrationTest.php
@@ -1,15 +1,18 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests if configuration overrides correctly affect cacheability metadata.
  *
  * @group config
  */
-class CacheabilityMetadataConfigOverrideIntegrationTest extends WebTestBase {
+class CacheabilityMetadataConfigOverrideIntegrationTest extends BrowserTestBase {
+
+  use AssertPageCacheContextsAndTagsTrait;
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/config/src/Tests/ConfigEntityFormOverrideTest.php b/core/modules/config/tests/src/Functional/ConfigEntityFormOverrideTest.php
similarity index 87%
rename from core/modules/config/src/Tests/ConfigEntityFormOverrideTest.php
rename to core/modules/config/tests/src/Functional/ConfigEntityFormOverrideTest.php
index 41419b0..2f48a7c 100644
--- a/core/modules/config/src/Tests/ConfigEntityFormOverrideTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigEntityFormOverrideTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests that config overrides do not bleed through in entity forms and lists.
  *
  * @group config
  */
-class ConfigEntityFormOverrideTest extends WebTestBase {
+class ConfigEntityFormOverrideTest extends BrowserTestBase {
 
   /**
    * {@inheritdoc}
@@ -46,7 +46,7 @@ public function testFormsWithOverrides() {
     // Test that the original label on the editing page is intact.
     $this->drupalGet('admin/structure/config_test/manage/dotted.default');
     $elements = $this->xpath('//input[@name="label"]');
-    $this->assertIdentical((string) $elements[0]['value'], $original_label);
+    $this->assertIdentical((string) $elements[0]->getValue(), $original_label);
     $this->assertNoText($overridden_label);
 
     // Change to a new label and test that the listing now has the edited label.
@@ -61,7 +61,7 @@ public function testFormsWithOverrides() {
     // Test that the editing page now has the edited label.
     $this->drupalGet('admin/structure/config_test/manage/dotted.default');
     $elements = $this->xpath('//input[@name="label"]');
-    $this->assertIdentical((string) $elements[0]['value'], $edited_label);
+    $this->assertIdentical((string) $elements[0]->getValue(), $edited_label);
 
     // Test that the overridden label is still loaded with the entity.
     $this->assertEqual($config_test_storage->load('dotted.default')->label(), $overridden_label);
diff --git a/core/modules/config/src/Tests/ConfigEntityListTest.php b/core/modules/config/tests/src/Functional/ConfigEntityListTest.php
similarity index 96%
rename from core/modules/config/src/Tests/ConfigEntityListTest.php
rename to core/modules/config/tests/src/Functional/ConfigEntityListTest.php
index e9950ea..69ef797 100644
--- a/core/modules/config/src/Tests/ConfigEntityListTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigEntityListTest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
 use Drupal\config_test\Entity\ConfigTest;
 use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the listing of configuration entities.
  *
  * @group config
  */
-class ConfigEntityListTest extends WebTestBase {
+class ConfigEntityListTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -168,7 +168,7 @@ public function testListUI() {
     // Test the contents of each th cell.
     $expected_items = ['Label', 'Machine name', 'Operations'];
     foreach ($elements as $key => $element) {
-      $this->assertIdentical((string) $element[0], $expected_items[$key]);
+      $this->assertIdentical($element->getText(), $expected_items[$key]);
     }
 
     // Check the number of table row cells.
@@ -178,9 +178,9 @@ public function testListUI() {
     // Check the contents of each row cell. The first cell contains the label,
     // the second contains the machine name, and the third contains the
     // operations list.
-    $this->assertIdentical((string) $elements[0], 'Default');
-    $this->assertIdentical((string) $elements[1], 'dotted.default');
-    $this->assertTrue($elements[2]->children()->xpath('//ul'), 'Operations list found.');
+    $this->assertIdentical($elements[0]->getText(), 'Default');
+    $this->assertIdentical($elements[1]->getText(), 'dotted.default');
+    $this->assertNotEmpty($elements[2]->find('xpath', '//ul'), 'Operations list found.');
 
     // Add a new entity using the operations link.
     $this->assertLink('Add test configuration');
diff --git a/core/modules/config/src/Tests/ConfigEntityTest.php b/core/modules/config/tests/src/Functional/ConfigEntityTest.php
similarity index 69%
rename from core/modules/config/src/Tests/ConfigEntityTest.php
rename to core/modules/config/tests/src/Functional/ConfigEntityTest.php
index c0dc97b..6c515f5 100644
--- a/core/modules/config/src/Tests/ConfigEntityTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigEntityTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityMalformedException;
@@ -8,14 +8,14 @@
 use Drupal\Core\Config\Entity\ConfigEntityStorage;
 use Drupal\Core\Config\Entity\Exception\ConfigEntityIdLengthException;
 use Drupal\Core\Url;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests configuration entities.
  *
  * @group config
  */
-class ConfigEntityTest extends WebTestBase {
+class ConfigEntityTest extends BrowserTestBase {
 
   /**
    * The maximum length for the entity storage used in this test.
@@ -233,112 +233,14 @@ public function testCRUD() {
   public function testCRUDUI() {
     $this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
 
-    $id = strtolower($this->randomMachineName());
-    $label1 = $this->randomMachineName();
-    $label2 = $this->randomMachineName();
-    $label3 = $this->randomMachineName();
-    $message_insert = format_string('%label configuration has been created.', ['%label' => $label1]);
-    $message_update = format_string('%label configuration has been updated.', ['%label' => $label2]);
-    $message_delete = format_string('The test configuration %label has been deleted.', ['%label' => $label2]);
-
-    // Create a configuration entity.
-    $edit = [
-      'id' => $id,
-      'label' => $label1,
-    ];
-    $this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save');
-    $this->assertUrl('admin/structure/config_test');
-    $this->assertResponse(200);
-    $this->assertRaw($message_insert);
-    $this->assertNoRaw($message_update);
-    $this->assertLinkByHref("admin/structure/config_test/manage/$id");
-
-    // Update the configuration entity.
-    $edit = [
-      'label' => $label2,
-    ];
-    $this->drupalPostForm("admin/structure/config_test/manage/$id", $edit, 'Save');
-    $this->assertUrl('admin/structure/config_test');
-    $this->assertResponse(200);
-    $this->assertNoRaw($message_insert);
-    $this->assertRaw($message_update);
-    $this->assertLinkByHref("admin/structure/config_test/manage/$id");
-    $this->assertLinkByHref("admin/structure/config_test/manage/$id/delete");
-
-    // Delete the configuration entity.
-    $this->drupalGet("admin/structure/config_test/manage/$id");
-    $this->clickLink(t('Delete'));
-    $this->assertUrl("admin/structure/config_test/manage/$id/delete");
-    $this->drupalPostForm(NULL, [], 'Delete');
-    $this->assertUrl('admin/structure/config_test');
-    $this->assertResponse(200);
-    $this->assertNoRaw($message_update);
-    $this->assertRaw($message_delete);
-    $this->assertNoText($label1);
-    $this->assertNoLinkByHref("admin/structure/config_test/manage/$id");
-
-    // Re-create a configuration entity.
-    $edit = [
-      'id' => $id,
-      'label' => $label1,
-    ];
-    $this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save');
-    $this->assertUrl('admin/structure/config_test');
-    $this->assertResponse(200);
-    $this->assertText($label1);
-    $this->assertLinkByHref("admin/structure/config_test/manage/$id");
-
-    // Rename the configuration entity's ID/machine name.
-    $edit = [
-      'id' => strtolower($this->randomMachineName()),
-      'label' => $label3,
-    ];
-    $this->drupalPostForm("admin/structure/config_test/manage/$id", $edit, 'Save');
-    $this->assertUrl('admin/structure/config_test');
-    $this->assertResponse(200);
-    $this->assertNoText($label1);
-    $this->assertNoText($label2);
-    $this->assertText($label3);
-    $this->assertNoLinkByHref("admin/structure/config_test/manage/$id");
-    $id = $edit['id'];
-    $this->assertLinkByHref("admin/structure/config_test/manage/$id");
-
-    // Create a configuration entity with '0' machine name.
-    $edit = [
-      'id' => '0',
-      'label' => '0',
-    ];
-    $this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save');
-    $this->assertResponse(200);
-    $message_insert = format_string('%label configuration has been created.', ['%label' => $edit['label']]);
-    $this->assertRaw($message_insert);
-    $this->assertLinkByHref('admin/structure/config_test/manage/0');
-    $this->assertLinkByHref('admin/structure/config_test/manage/0/delete');
-    $this->drupalPostForm('admin/structure/config_test/manage/0/delete', [], 'Delete');
-    $this->assertFalse(entity_load('config_test', '0'), 'Test entity deleted');
-
-    // Create a configuration entity with a property that uses AJAX to show
-    // extra form elements.
-    $this->drupalGet('admin/structure/config_test/add');
-
-    // Test that the dependent element is not shown initially.
-    $this->assertFieldByName('size');
-    $this->assertNoFieldByName('size_value');
-
+    // Create a configuration entity with a property that uses the non-JS case
+    // by using a 'js-hidden' submit button.
     $id = strtolower($this->randomMachineName());
     $edit = [
       'id' => $id,
       'label' => $this->randomString(),
       'size' => 'custom',
     ];
-    $this->drupalPostAjaxForm(NULL, $edit, 'size');
-
-    // Check that the dependent element is shown after selecting a 'size' value.
-    $this->assertFieldByName('size');
-    $this->assertFieldByName('size_value');
-
-    // Test the same scenario but it in a non-JS case by using a 'js-hidden'
-    // submit button.
     $this->drupalGet('admin/structure/config_test/add');
     $this->assertFieldByName('size');
     $this->assertNoFieldByName('size_value');
diff --git a/core/modules/config/src/Tests/ConfigExportImportUITest.php b/core/modules/config/tests/src/Functional/ConfigExportImportUITest.php
similarity index 99%
rename from core/modules/config/src/Tests/ConfigExportImportUITest.php
rename to core/modules/config/tests/src/Functional/ConfigExportImportUITest.php
index 9ba59a8..96a80a6 100644
--- a/core/modules/config/src/Tests/ConfigExportImportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigExportImportUITest.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Archiver\ArchiveTar;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the user interface for importing/exporting configuration.
@@ -17,7 +17,7 @@
  *
  * @group config
  */
-class ConfigExportImportUITest extends WebTestBase {
+class ConfigExportImportUITest extends BrowserTestBase {
 
   /**
    * The contents of the config export tarball, held between test methods.
diff --git a/core/modules/config/src/Tests/ConfigExportUITest.php b/core/modules/config/tests/src/Functional/ConfigExportUITest.php
similarity index 96%
rename from core/modules/config/src/Tests/ConfigExportUITest.php
rename to core/modules/config/tests/src/Functional/ConfigExportUITest.php
index c9f53b3..d9bdbc4 100644
--- a/core/modules/config/src/Tests/ConfigExportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigExportUITest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Core\Archiver\Tar;
 use Drupal\Core\Serialization\Yaml;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the user interface for exporting configuration.
  *
  * @group config
  */
-class ConfigExportUITest extends WebTestBase {
+class ConfigExportUITest extends BrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/config/src/Tests/ConfigFormOverrideTest.php b/core/modules/config/tests/src/Functional/ConfigFormOverrideTest.php
similarity index 81%
rename from core/modules/config/src/Tests/ConfigFormOverrideTest.php
rename to core/modules/config/tests/src/Functional/ConfigFormOverrideTest.php
index f721eeb..59276e3 100644
--- a/core/modules/config/src/Tests/ConfigFormOverrideTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigFormOverrideTest.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests config overrides do not appear on forms that extend ConfigFormBase.
@@ -10,7 +10,7 @@
  * @group config
  * @see \Drupal\Core\Form\ConfigFormBase
  */
-class ConfigFormOverrideTest extends WebTestBase {
+class ConfigFormOverrideTest extends BrowserTestBase {
 
   /**
    * Tests that overrides do not affect forms.
@@ -32,7 +32,7 @@ public function testFormsWithOverrides() {
     $this->drupalGet('admin/config/system/site-information');
     $this->assertTitle('Basic site settings | ' . $overridden_name);
     $elements = $this->xpath('//input[@name="site_name"]');
-    $this->assertIdentical((string) $elements[0]['value'], 'Drupal');
+    $this->assertIdentical((string) $elements[0]->getValue(), 'Drupal');
 
     // Submit the form and ensure the site name is not changed.
     $edit = [
@@ -41,7 +41,7 @@ public function testFormsWithOverrides() {
     $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
     $this->assertTitle('Basic site settings | ' . $overridden_name);
     $elements = $this->xpath('//input[@name="site_name"]');
-    $this->assertIdentical((string) $elements[0]['value'], $edit['site_name']);
+    $this->assertIdentical((string) $elements[0]->getValue(), $edit['site_name']);
   }
 
 }
diff --git a/core/modules/config/src/Tests/ConfigImportAllTest.php b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
similarity index 97%
rename from core/modules/config/src/Tests/ConfigImportAllTest.php
rename to core/modules/config/tests/src/Functional/ConfigImportAllTest.php
index 459be7a..0608681 100644
--- a/core/modules/config/src/Tests/ConfigImportAllTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
@@ -1,12 +1,13 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Core\Config\StorageComparer;
 use Drupal\filter\Entity\FilterFormat;
-use Drupal\system\Tests\Module\ModuleTestBase;
 use Drupal\shortcut\Entity\Shortcut;
 use Drupal\taxonomy\Entity\Term;
+use Drupal\Tests\SchemaCheckTestTrait;
+use Drupal\Tests\system\Functional\Module\ModuleTestBase;
 
 /**
  * Tests the largest configuration import possible with all available modules.
diff --git a/core/modules/config/src/Tests/ConfigImportInstallProfileTest.php b/core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php
similarity index 94%
rename from core/modules/config/src/Tests/ConfigImportInstallProfileTest.php
rename to core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php
index eaece36..8b0787d 100644
--- a/core/modules/config/src/Tests/ConfigImportInstallProfileTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the importing/exporting configuration based on the install profile.
  *
  * @group config
  */
-class ConfigImportInstallProfileTest extends WebTestBase {
+class ConfigImportInstallProfileTest extends BrowserTestBase {
 
   /**
    * The profile to install as a basis for testing.
diff --git a/core/modules/config/src/Tests/ConfigImportUITest.php b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
similarity index 99%
rename from core/modules/config/src/Tests/ConfigImportUITest.php
rename to core/modules/config/tests/src/Functional/ConfigImportUITest.php
index 772dada..4094af6 100644
--- a/core/modules/config/src/Tests/ConfigImportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
@@ -1,18 +1,18 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\InstallStorage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the user interface for importing/exporting configuration.
  *
  * @group config
  */
-class ConfigImportUITest extends WebTestBase {
+class ConfigImportUITest extends BrowserTestBase {
 
   /**
    * Modules to install.
diff --git a/core/modules/config/src/Tests/ConfigImportUploadTest.php b/core/modules/config/tests/src/Functional/ConfigImportUploadTest.php
similarity index 86%
rename from core/modules/config/src/Tests/ConfigImportUploadTest.php
rename to core/modules/config/tests/src/Functional/ConfigImportUploadTest.php
index 5e21295..955842d 100644
--- a/core/modules/config/src/Tests/ConfigImportUploadTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigImportUploadTest.php
@@ -1,15 +1,18 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\TestFileCreationTrait;
 
 /**
  * Tests importing configuration from an uploaded file.
  *
  * @group config
  */
-class ConfigImportUploadTest extends WebTestBase {
+class ConfigImportUploadTest extends BrowserTestBase {
+
+  use TestFileCreationTrait;
 
   /**
    * A user with the 'import configuration' permission.
@@ -41,7 +44,7 @@ public function testImport() {
     $this->assertResponse(200);
 
     // Attempt to upload a non-tar file.
-    $text_file = current($this->drupalGetTestFiles('text'));
+    $text_file = $this->getTestFiles('text')[0];
     $edit = ['files[import_tarball]' => drupal_realpath($text_file->uri)];
     $this->drupalPostForm('admin/config/development/configuration/full/import', $edit, t('Upload'));
     $this->assertText(t('Could not extract the contents of the tar file'));
diff --git a/core/modules/config/src/Tests/ConfigInstallWebTest.php b/core/modules/config/tests/src/Functional/ConfigInstallWebTest.php
similarity index 91%
rename from core/modules/config/src/Tests/ConfigInstallWebTest.php
rename to core/modules/config/tests/src/Functional/ConfigInstallWebTest.php
index 63ecb5b..3d694bd 100644
--- a/core/modules/config/src/Tests/ConfigInstallWebTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigInstallWebTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Core\Config\PreExistingConfigException;
 use Drupal\Core\Config\StorageInterface;
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests installation and removal of configuration objects in install, disable
@@ -13,7 +13,7 @@
  *
  * @group config
  */
-class ConfigInstallWebTest extends WebTestBase {
+class ConfigInstallWebTest extends BrowserTestBase {
 
   /**
    * The admin user used in this test.
@@ -51,6 +51,7 @@ public function testIntegrationModuleReinstallation() {
 
     // Install the integration module.
     \Drupal::service('module_installer')->install(['config_integration_test']);
+    $this->resetAll();
 
     // Verify that default module config exists.
     \Drupal::configFactory()->reset($default_config);
@@ -148,7 +149,8 @@ public function testPreExistingConfigInstall() {
       ->save();
 
     $this->drupalPostForm('admin/modules', ['modules[config_install_fail_test][enable]' => TRUE], t('Install'));
-    $this->assertRaw('Unable to install Configuration install fail test, <em class="placeholder">config_test.dynamic.dotted.default, language/fr/config_test.dynamic.dotted.default</em> already exist in active configuration.');
+    $placeholder = str_replace('/', DIRECTORY_SEPARATOR,'language/fr/config_test.dynamic.dotted.default');
+    $this->assertRaw('Unable to install Configuration install fail test, <em class="placeholder">config_test.dynamic.dotted.default, ' . $placeholder . '</em> already exist in active configuration.');
 
     // Test installing a theme through the UI that has existing configuration.
     // This relies on the fact the config_test has been installed and created
@@ -156,8 +158,9 @@ public function testPreExistingConfigInstall() {
     // override created still exists.
     $this->drupalGet('admin/appearance');
     $url = $this->xpath("//a[contains(@href,'config_clash_test_theme') and contains(@href,'/install?')]/@href")[0];
-    $this->drupalGet($this->getAbsoluteUrl($url));
-    $this->assertRaw('Unable to install config_clash_test_theme, <em class="placeholder">config_test.dynamic.dotted.default, language/fr/config_test.dynamic.dotted.default</em> already exist in active configuration.');
+    $this->drupalGet($this->getAbsoluteUrl($url->getText()));
+    $placeholder = str_replace('/', DIRECTORY_SEPARATOR, 'language/fr/config_test.dynamic.dotted.default');
+    $this->assertRaw('Unable to install config_clash_test_theme, <em class="placeholder">config_test.dynamic.dotted.default, ' . $placeholder . '</em> already exist in active configuration.');
 
     // Test installing a theme through the API that has existing configuration.
     try {
@@ -167,7 +170,9 @@ public function testPreExistingConfigInstall() {
     catch (PreExistingConfigException $e) {
       $this->assertEqual($e->getExtension(), 'config_clash_test_theme');
       $this->assertEqual($e->getConfigObjects(), [StorageInterface::DEFAULT_COLLECTION => ['config_test.dynamic.dotted.default'], 'language.fr' => ['config_test.dynamic.dotted.default']]);
-      $this->assertEqual($e->getMessage(), 'Configuration objects (config_test.dynamic.dotted.default, language/fr/config_test.dynamic.dotted.default) provided by config_clash_test_theme already exist in active configuration');
+      $placeholder = str_replace('/', DIRECTORY_SEPARATOR, 'language/fr/config_test.dynamic.dotted.default');
+      $expected = str_replace('/', DIRECTORY_SEPARATOR, 'Configuration objects (config_test.dynamic.dotted.default, ' . $placeholder . ') provided by config_clash_test_theme already exist in active configuration');
+      $this->assertEqual($e->getMessage(), $expected);
     }
   }
 
diff --git a/core/modules/config/src/Tests/ConfigSingleImportExportTest.php b/core/modules/config/tests/src/Functional/ConfigSingleImportExportTest.php
similarity index 93%
rename from core/modules/config/src/Tests/ConfigSingleImportExportTest.php
rename to core/modules/config/tests/src/Functional/ConfigSingleImportExportTest.php
index 607e80c..5c0b420 100644
--- a/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigSingleImportExportTest.php
@@ -1,16 +1,16 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
 use Drupal\Core\Serialization\Yaml;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the user interface for importing/exporting a single configuration.
  *
  * @group config
  */
-class ConfigSingleImportExportTest extends WebTestBase {
+class ConfigSingleImportExportTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -225,16 +225,18 @@ public function testExport() {
     $this->drupalGet('admin/config/development/configuration/single/export/system.simple');
     $this->assertFieldByXPath('//select[@name="config_type"]//option[@selected="selected"]', t('Simple configuration'), 'The simple configuration option is selected when specified in the URL.');
     // Spot check several known simple configuration files.
-    $element = $this->xpath('//select[@name="config_name"]');
-    $options = $this->getAllOptions($element[0]);
+    $element = $this->xpath('//select[@name="config_name"]')[0];
+    $options = $element->findAll('css', 'option');
     $expected_options = ['system.site', 'user.settings'];
     foreach ($options as &$option) {
-      $option = (string) $option;
+      $option = (string) $option->getValue();
     }
     $this->assertIdentical($expected_options, array_intersect($expected_options, $options), 'The expected configuration files are listed.');
 
     $this->drupalGet('admin/config/development/configuration/single/export/system.simple/system.image');
-    $this->assertFieldByXPath('//textarea[@name="export"]', "toolkit: gd\n_core:\n  default_config_hash: durWHaKeBaq4d9Wpi4RqwADj1OufDepcnJuhVLmKN24\n", 'The expected system configuration is displayed.');
+    $actual = $this->xpath('//textarea[@name="export"]')[0]->getValue();
+    $expected = "toolkit: gd\n_core:\n  default_config_hash: durWHaKeBaq4d9Wpi4RqwADj1OufDepcnJuhVLmKN24\n";
+    $this->assertEquals($expected, $actual, 'The expected system configuration is displayed.');
 
     $this->drupalGet('admin/config/development/configuration/single/export/date_format');
     $this->assertFieldByXPath('//select[@name="config_type"]//option[@selected="selected"]', t('Date format'), 'The date format entity type is selected when specified in the URL.');
@@ -243,7 +245,7 @@ public function testExport() {
     $this->assertFieldByXPath('//select[@name="config_name"]//option[@selected="selected"]', t('Fallback date format (fallback)'), 'The fallback date format config entity is selected when specified in the URL.');
 
     $fallback_date = \Drupal::entityManager()->getStorage('date_format')->load('fallback');
-    $yaml_text = (string) $this->xpath('//textarea[@name="export"]')[0];
+    $yaml_text = $this->xpath('//textarea[@name="export"]')[0]->getValue();
     $this->assertEqual(Yaml::decode($yaml_text), $fallback_date->toArray(), 'The fallback date format config entity export code is displayed.');
   }
 
diff --git a/core/modules/config/src/Tests/LanguageNegotiationFormOverrideTest.php b/core/modules/config/tests/src/Functional/LanguageNegotiationFormOverrideTest.php
similarity index 93%
rename from core/modules/config/src/Tests/LanguageNegotiationFormOverrideTest.php
rename to core/modules/config/tests/src/Functional/LanguageNegotiationFormOverrideTest.php
index ba67960..6c4e1bb 100644
--- a/core/modules/config/src/Tests/LanguageNegotiationFormOverrideTest.php
+++ b/core/modules/config/tests/src/Functional/LanguageNegotiationFormOverrideTest.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\config\Tests;
+namespace Drupal\Tests\config\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests language-negotiation overrides are not on language-negotiation form.
@@ -10,7 +10,7 @@
  * @group config
  * @see \Drupal\Core\Form\ConfigFormBase
  */
-class LanguageNegotiationFormOverrideTest extends WebTestBase {
+class LanguageNegotiationFormOverrideTest extends BrowserTestBase {
 
   public static $modules = ['language', 'locale', 'locale_test'];
 
diff --git a/core/modules/config/tests/src/FunctionalJavascript/ConfigEntityTest.php b/core/modules/config/tests/src/FunctionalJavascript/ConfigEntityTest.php
new file mode 100644
index 0000000..aad3cf2
--- /dev/null
+++ b/core/modules/config/tests/src/FunctionalJavascript/ConfigEntityTest.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace Drupal\Tests\config\FunctionalJavascript;
+
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Tests the View UI filter criteria group dialog.
+ *
+ * @group views_ui
+ */
+class ConfigEntityTest extends JavascriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['config_test'];
+
+  /**
+   * Tests CRUD operations through the UI.
+   */
+  public function testCRUDUI() {
+    $this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
+
+    $id = strtolower($this->randomMachineName());
+    $label1 = $this->randomMachineName();
+    $label2 = $this->randomMachineName();
+    $label3 = $this->randomMachineName();
+    $message_insert = new FormattableMarkup('%label configuration has been created.', array('%label' => $label1));
+    $message_update = new FormattableMarkup('%label configuration has been updated.', array('%label' => $label2));
+    $message_delete = new FormattableMarkup('The test configuration %label has been deleted.', array('%label' => $label2));
+
+    // Create a configuration entity.
+    $this->drupalGet('admin/structure/config_test/add');
+
+    $session = $this->getSession();
+    $assert_session = $this->assertSession();
+    $page = $session->getPage();
+
+    $field_id = $page->findField('id');
+    $field_label = $page->findField('label');
+    $button_save = $page->findButton('Save');
+
+    // Set values for the configuration entity and submit the form.
+    $field_id->setValue($id);
+    $field_label->setValue($label1);
+    $button_save->click();
+
+    $assert_session->addressEquals('admin/structure/config_test');
+    $assert_session->statusCodeEquals(200);
+    $assert_session->responseContains($message_insert);
+    $assert_session->responseNotContains($message_update);
+    $this->assertNotEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '"]'));
+
+    // Update the configuration entity.
+    $this->drupalGet("admin/structure/config_test/manage/$id");
+    $field_label->setValue($label2);
+    $button_save->click();
+    $assert_session->addressEquals('admin/structure/config_test');
+    $assert_session->statusCodeEquals(200);
+    $assert_session->responseNotContains($message_insert);
+    $assert_session->responseContains($message_update);
+    $this->assertNotEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '"]'));
+    $this->assertNotEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '/delete"]'));
+
+    // Delete the configuration entity.
+    $this->drupalGet("admin/structure/config_test/manage/$id");
+    $this->clickLink(t('Delete'));
+    $assert_session->addressEquals("admin/structure/config_test/manage/$id/delete");
+    $page->findButton('Delete')->click();
+
+    $assert_session->addressEquals('admin/structure/config_test');
+    $assert_session->statusCodeEquals(200);
+    $assert_session->responseNotContains($message_update);
+    $assert_session->responseContains($message_delete);
+    $assert_session->responseNotContains($label1);
+    $this->assertEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '"]'));
+
+    // Re-create a configuration entity.
+    $this->drupalGet('admin/structure/config_test/add');
+    $field_id->setValue($id);
+    $field_label->setValue($label1);
+    $button_save->click();
+
+    $assert_session->addressEquals('admin/structure/config_test');
+    $assert_session->statusCodeEquals(200);
+    $assert_session->responseContains($label1);
+    $this->assertNotEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '"]'));
+
+    // Rename the configuration entity's ID/machine name.
+    $new_id = strtolower($this->randomMachineName());
+    $this->drupalGet("admin/structure/config_test/manage/$id");
+    $field_id->setValue($new_id);
+    $field_label->setValue($label3);
+    $button_save->click();
+
+    $assert_session->addressEquals('admin/structure/config_test');
+    $assert_session->statusCodeEquals(200);
+    $assert_session->responseNotContains($label1);
+    $assert_session->responseNotContains($label2);
+    $assert_session->responseContains($label3);
+    $this->assertEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '"]'));
+
+    $id = $new_id;
+    $this->assertNotEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/' . $id . '"]'));
+
+    // Create a configuration entity with '0' machine name.
+    $this->drupalGet('admin/structure/config_test/add');
+    $field_id->setValue('0');
+    $field_label->setValue('0');
+    $button_save->click();
+
+    $assert_session->statusCodeEquals(200);
+    $message_insert = new FormattableMarkup('%label configuration has been created.', array('%label' => '0'));
+    $assert_session->responseContains($message_insert);
+
+    $this->assertNotEmpty($page->find('css' , 'a[href="/admin/structure/config_test/manage/0"]'));
+    $delete_link = $page->find('css' , 'a[href="/admin/structure/config_test/manage/0/delete"]');
+
+    // Expand the options.
+    $ul = $delete_link->getParent()->getParent();
+    $ul->find('css', '.dropbutton-toggle button')->click();
+    $this->assertTrue($delete_link->isVisible());
+
+    // Navigate to the delete page and submit the delete form.
+    $delete_link->click();
+    $page->findButton('Delete')->click();
+
+    $entity = \Drupal::entityTypeManager()->getStorage('config_test')->load('0');
+    $this->assertFalse($entity, 'Test entity deleted');
+
+    // Create a configuration entity with a property that uses AJAX to show
+    // extra form elements.
+    $this->drupalGet('admin/structure/config_test/add');
+
+    // Test that the dependent element is not shown initially.
+    $field_size = $page->findField('size');
+    $field_size_value = $page->findField('size_value');
+    $this->assertNotEmpty($field_size);
+    $this->assertEmpty($field_size_value);
+
+    $id = strtolower($this->randomMachineName());
+    $field_id->setValue($id);
+    $field_label->setValue($this->randomString());
+    $field_size->setValue('custom');
+    $assert_session->assertWaitOnAjaxRequest();
+
+    // Check that the dependent element is shown after selecting a 'size' value.
+    $field_size_value = $page->findField('size_value');
+    $this->assertNotEmpty($field_size);
+    $this->assertNotEmpty($field_size_value);
+
+    $field_size_value->setValue('medium');
+    $button_save->click();
+
+    $entity = \Drupal::entityTypeManager()->getStorage('config_test')->load($id);
+    $this->assertEquals('custom', $entity->get('size'));
+    $this->assertEquals('medium', $entity->get('size_value'));
+  }
+
+}
