diff --git a/core/modules/aggregator/src/Tests/AddFeedTest.php b/core/modules/aggregator/tests/src/Functional/AddFeedTest.php
similarity index 98%
rename from core/modules/aggregator/src/Tests/AddFeedTest.php
rename to core/modules/aggregator/tests/src/Functional/AddFeedTest.php
index b7ffe5f..90fff77 100644
--- a/core/modules/aggregator/src/Tests/AddFeedTest.php
+++ b/core/modules/aggregator/tests/src/Functional/AddFeedTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Add feed test.
diff --git a/core/modules/aggregator/src/Tests/AggregatorAdminTest.php b/core/modules/aggregator/tests/src/Functional/AggregatorAdminTest.php
similarity index 86%
rename from core/modules/aggregator/src/Tests/AggregatorAdminTest.php
rename to core/modules/aggregator/tests/src/Functional/AggregatorAdminTest.php
index 249817f..329dee1 100644
--- a/core/modules/aggregator/src/Tests/AggregatorAdminTest.php
+++ b/core/modules/aggregator/tests/src/Functional/AggregatorAdminTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Tests aggregator admin pages.
@@ -67,18 +67,21 @@ function testOverviewPage() {
     // Check if the amount of feeds in the overview matches the amount created.
     $this->assertEqual(1, count($result), 'Created feed is found in the overview');
     // Check if the fields in the table match with what's expected.
-    $this->assertEqual($feed->label(), (string) $result[0]->td[0]->a);
+    $link = $this->xpath('//table/tbody/tr//td[1]/a');
+    $this->assertEqual($feed->label(), $link[0]->getText());
     $count = $this->container->get('entity.manager')->getStorage('aggregator_item')->getItemCount($feed);
-    $this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), (string) $result[0]->td[1]);
+    $td = $this->xpath('//table/tbody/tr//td[2]');
+    $this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), $td[0]->getText());
 
     // Update the items of the first feed.
     $feed->refreshItems();
     $this->drupalGet('admin/config/services/aggregator');
-    $result = $this->xpath('//table/tbody/tr');
     // Check if the fields in the table match with what's expected.
-    $this->assertEqual($feed->label(), (string) $result[0]->td[0]->a);
+    $link = $this->xpath('//table/tbody/tr//td[1]/a');
+    $this->assertEqual($feed->label(), $link[0]->getText());
     $count = $this->container->get('entity.manager')->getStorage('aggregator_item')->getItemCount($feed);
-    $this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), (string) $result[0]->td[1]);
+    $td = $this->xpath('//table/tbody/tr//td[2]');
+    $this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), $td[0]->getText());
   }
 
 }
diff --git a/core/modules/aggregator/src/Tests/AggregatorCronTest.php b/core/modules/aggregator/tests/src/Functional/AggregatorCronTest.php
similarity index 97%
rename from core/modules/aggregator/src/Tests/AggregatorCronTest.php
rename to core/modules/aggregator/tests/src/Functional/AggregatorCronTest.php
index 34a4cb9..ef8dc41 100644
--- a/core/modules/aggregator/src/Tests/AggregatorCronTest.php
+++ b/core/modules/aggregator/tests/src/Functional/AggregatorCronTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Update feeds on cron.
diff --git a/core/modules/aggregator/src/Tests/AggregatorRenderingTest.php b/core/modules/aggregator/tests/src/Functional/AggregatorRenderingTest.php
similarity index 93%
rename from core/modules/aggregator/src/Tests/AggregatorRenderingTest.php
rename to core/modules/aggregator/tests/src/Functional/AggregatorRenderingTest.php
index 888f1da..aa48927 100644
--- a/core/modules/aggregator/src/Tests/AggregatorRenderingTest.php
+++ b/core/modules/aggregator/tests/src/Functional/AggregatorRenderingTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\views\Entity\View;
@@ -132,10 +132,11 @@ public function testFeedPage() {
 
     // Check the opml aggregator page.
     $this->drupalGet('aggregator/opml');
-    $outline = $this->xpath('//outline[1]');
-    $this->assertEqual($outline[0]['type'], 'rss', 'The correct type attribute is used for rss OPML.');
-    $this->assertEqual($outline[0]['text'], $feed->label(), 'The correct text attribute is used for rss OPML.');
-    $this->assertEqual($outline[0]['xmlurl'], $feed->getUrl(), 'The correct xmlUrl attribute is used for rss OPML.');
+    $xml = simplexml_load_string($this->getRawContent());
+    $attributes = $xml->xpath('//outline[1]')[0]->attributes();
+    self::assertEquals($attributes->type, 'rss');
+    self::assertEquals($attributes->text, $feed->label());
+    self::assertEquals($attributes->xmlUrl, $feed->getUrl());
 
     // Check for the presence of a pager.
     $this->drupalGet('aggregator/sources/' . $feed->id());
diff --git a/core/modules/aggregator/src/Tests/AggregatorTestBase.php b/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php
similarity index 97%
rename from core/modules/aggregator/src/Tests/AggregatorTestBase.php
rename to core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php
index 15be144..c271fc7 100644
--- a/core/modules/aggregator/src/Tests/AggregatorTestBase.php
+++ b/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php
@@ -1,16 +1,16 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 use Drupal\aggregator\Entity\Feed;
 use Drupal\Component\Utility\Html;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 use Drupal\aggregator\FeedInterface;
 
 /**
  * Defines a base class for testing the Aggregator module.
  */
-abstract class AggregatorTestBase extends WebTestBase {
+abstract class AggregatorTestBase extends BrowserTestBase {
 
   /**
    * A user with permission to administer feeds and create content.
@@ -61,7 +61,7 @@ protected function setUp() {
   public function createFeed($feed_url = NULL, array $edit = array()) {
     $edit = $this->getFeedEditArray($feed_url, $edit);
     $this->drupalPostForm('aggregator/sources/add', $edit, t('Save'));
-    $this->assertText(t('The feed @name has been added.', array('@name' => $edit['title[0][value]'])), format_string('The feed @name has been added.', array('@name' => $edit['title[0][value]'])));
+    $this->assertText(t("The feed {$edit['title[0][value]']} has been added."), format_string('The feed @name has been added.', array('@name' => $edit['title[0][value]'])));
 
     // Verify that the creation message contains a link to a feed.
     $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'aggregator/sources/'));
diff --git a/core/modules/aggregator/src/Tests/DeleteFeedItemTest.php b/core/modules/aggregator/tests/src/Functional/DeleteFeedItemTest.php
similarity index 96%
rename from core/modules/aggregator/src/Tests/DeleteFeedItemTest.php
rename to core/modules/aggregator/tests/src/Functional/DeleteFeedItemTest.php
index 0261ed5..95202b8 100644
--- a/core/modules/aggregator/src/Tests/DeleteFeedItemTest.php
+++ b/core/modules/aggregator/tests/src/Functional/DeleteFeedItemTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Delete feed items from a feed.
diff --git a/core/modules/aggregator/src/Tests/DeleteFeedTest.php b/core/modules/aggregator/tests/src/Functional/DeleteFeedTest.php
similarity index 97%
rename from core/modules/aggregator/src/Tests/DeleteFeedTest.php
rename to core/modules/aggregator/tests/src/Functional/DeleteFeedTest.php
index 4cde81a..5bf5bd3 100644
--- a/core/modules/aggregator/src/Tests/DeleteFeedTest.php
+++ b/core/modules/aggregator/tests/src/Functional/DeleteFeedTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Delete feed test.
diff --git a/core/modules/aggregator/src/Tests/FeedAdminDisplayTest.php b/core/modules/aggregator/tests/src/Functional/FeedAdminDisplayTest.php
similarity index 98%
rename from core/modules/aggregator/src/Tests/FeedAdminDisplayTest.php
rename to core/modules/aggregator/tests/src/Functional/FeedAdminDisplayTest.php
index b6e36e9..6ae627c 100644
--- a/core/modules/aggregator/src/Tests/FeedAdminDisplayTest.php
+++ b/core/modules/aggregator/tests/src/Functional/FeedAdminDisplayTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Tests the display of a feed on the feed aggregator list page.
diff --git a/core/modules/aggregator/src/Tests/FeedFetcherPluginTest.php b/core/modules/aggregator/tests/src/Functional/FeedFetcherPluginTest.php
similarity index 95%
rename from core/modules/aggregator/src/Tests/FeedFetcherPluginTest.php
rename to core/modules/aggregator/tests/src/Functional/FeedFetcherPluginTest.php
index 4aac851..1a03186 100644
--- a/core/modules/aggregator/src/Tests/FeedFetcherPluginTest.php
+++ b/core/modules/aggregator/tests/src/Functional/FeedFetcherPluginTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Tests the fetcher plugins functionality and discoverability.
diff --git a/core/modules/aggregator/src/Tests/FeedLanguageTest.php b/core/modules/aggregator/tests/src/Functional/FeedLanguageTest.php
similarity index 98%
rename from core/modules/aggregator/src/Tests/FeedLanguageTest.php
rename to core/modules/aggregator/tests/src/Functional/FeedLanguageTest.php
index af8335e..81f8b42 100644
--- a/core/modules/aggregator/src/Tests/FeedLanguageTest.php
+++ b/core/modules/aggregator/tests/src/Functional/FeedLanguageTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 use Drupal\language\Entity\ConfigurableLanguage;
 
diff --git a/core/modules/aggregator/src/Tests/FeedParserTest.php b/core/modules/aggregator/tests/src/Functional/FeedParserTest.php
similarity index 99%
rename from core/modules/aggregator/src/Tests/FeedParserTest.php
rename to core/modules/aggregator/tests/src/Functional/FeedParserTest.php
index 6c4a04d..00c7b70 100644
--- a/core/modules/aggregator/src/Tests/FeedParserTest.php
+++ b/core/modules/aggregator/tests/src/Functional/FeedParserTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 use Drupal\Core\Url;
 use Drupal\aggregator\Entity\Feed;
diff --git a/core/modules/aggregator/src/Tests/FeedProcessorPluginTest.php b/core/modules/aggregator/tests/src/Functional/FeedProcessorPluginTest.php
similarity index 97%
rename from core/modules/aggregator/src/Tests/FeedProcessorPluginTest.php
rename to core/modules/aggregator/tests/src/Functional/FeedProcessorPluginTest.php
index 8a7ade0..5527d95 100644
--- a/core/modules/aggregator/src/Tests/FeedProcessorPluginTest.php
+++ b/core/modules/aggregator/tests/src/Functional/FeedProcessorPluginTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 use Drupal\aggregator\Entity\Feed;
 use Drupal\aggregator\Entity\Item;
diff --git a/core/modules/aggregator/src/Tests/ImportOpmlTest.php b/core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php
similarity index 99%
rename from core/modules/aggregator/src/Tests/ImportOpmlTest.php
rename to core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php
index 1f1e90d..8994e3f 100644
--- a/core/modules/aggregator/src/Tests/ImportOpmlTest.php
+++ b/core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Tests OPML import.
diff --git a/core/modules/aggregator/src/Tests/UpdateFeedItemTest.php b/core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php
similarity index 98%
rename from core/modules/aggregator/src/Tests/UpdateFeedItemTest.php
rename to core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php
index ae78205..ba99dd0 100644
--- a/core/modules/aggregator/src/Tests/UpdateFeedItemTest.php
+++ b/core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 use Drupal\aggregator\Entity\Feed;
 
 /**
diff --git a/core/modules/aggregator/src/Tests/UpdateFeedTest.php b/core/modules/aggregator/tests/src/Functional/UpdateFeedTest.php
similarity index 97%
rename from core/modules/aggregator/src/Tests/UpdateFeedTest.php
rename to core/modules/aggregator/tests/src/Functional/UpdateFeedTest.php
index 8c797a5..bb830a5 100644
--- a/core/modules/aggregator/src/Tests/UpdateFeedTest.php
+++ b/core/modules/aggregator/tests/src/Functional/UpdateFeedTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
 
 /**
  * Update feed test.
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index ce2721b..4cecbb8 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -237,6 +237,20 @@
   protected $preserveGlobalState = FALSE;
 
   /**
+   * The number of meta refresh redirects to follow, or NULL if unlimited.
+   *
+   * @var null|int
+   */
+  protected $maximumMetaRefreshCount = NULL;
+
+  /**
+   * The number of meta refresh redirects followed during ::drupalGet().
+   *
+   * @var int
+   */
+  protected $metaRefreshCount = 0;
+
+  /**
    * Class name for HTML output logging.
    *
    * @var string
@@ -1580,6 +1594,44 @@ protected function getTextContent() {
   }
 
   /**
+   * Retrieves the raw content from the current page.
+   */
+  protected function getRawContent() {
+    return $this->getSession()->getPage()->getContent();
+  }
+
+  /**
+   * Runs cron.
+   */
+  protected function cronRun() {
+    /** @var \Drupal\Core\State\StateInterface $state */
+    $state = $this->container->get('state');
+    $this->drupalGet("cron/{$state->get('system.cron_key')}");
+  }
+
+  /**
+   * Checks for meta refresh tag and if found call drupalGet() recursively.
+   *
+   * This function looks for the http-equiv attribute to be set to "Refresh" and
+   * is case-sensitive.
+   *
+   * @return string|false
+   *   Either the new page content or FALSE.
+   */
+  protected function checkForMetaRefresh() {
+    $refresh = $this->cssSelect('meta[http-equiv="Refresh"]');
+    if (!empty($refresh) && (!isset($this->maximumMetaRefreshCount) || $this->metaRefreshCount < $this->maximumMetaRefreshCount)) {
+      // Parse the content attribute of the meta tag for the format:
+      // "[delay]: URL=[page_to_redirect_to]".
+      if (preg_match('/\d+;\s*URL=(?<url>.*)/i', $refresh[0]->getAttribute('content'), $match)) {
+        $this->metaRefreshCount++;
+        return $this->drupalGet($this->getAbsoluteUrl(Html::decodeEntities($match['url'])));
+      }
+    }
+    return FALSE;
+  }
+
+  /**
    * Performs an xpath search on the contents of the internal browser.
    *
    * The search is relative to the root element (HTML tag normally) of the page.
