diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index 04e98f1..21bc680 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -1326,4 +1326,45 @@ public function copyConfig(StorageInterface $source_storage, StorageInterface $t
       $target_storage->write($name, $source_storage->read($name));
     }
   }
+
+  /**
+   * Performs a CSS selection based search on the current page contents.
+   *
+   * Utilizes \PHPUnit_Util_XML::cssSelect to perform a CSS based search of the
+   * contents of the internal browser. The search is relative to the root
+   * element of the page (usually the HTML tag).
+   *
+   * @param string $selector
+   *   CSS selector to use in the search.
+   * @param string $contains
+   *   (optional) Filter matching nodes to those containing the given content.
+   *   TRUE will match all content. Note that due to limitations with
+   *   \PHPUnit_Util_XML::cssSelect this does not work when you pass a nested
+   *   selector such as 'li h2'.
+   * @param mixed $content
+   *   (optional) Content to parse for selector. Can be either a string or an
+   *   array containing \DOMElement objects, this allows to reuse the output of
+   *   this method. Defaults to $this->content.
+   *
+   * @return array
+   *   Array of matching \DOMElement nodes.
+   *
+   * @see \PHPUnit_Util_XML::cssSelect
+   */
+  protected function cssSelect($selector, $contains = TRUE, $content = FALSE) {
+    if (!$content && isset($this->content)) {
+      $content = $this->content;
+    }
+    if (is_array($content)) {
+      $content = array_reduce($content, function ($value, $item) {
+        $value .= $item->ownerDocument->saveHtml($item);
+        return $value;
+      }, '');
+    }
+    if ($nodes = \PHPUnit_Util_XML::cssSelect($selector, $contains, $content, TRUE)) {
+      return $nodes;
+    }
+    return array();
+  }
+
 }
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/CssSelectWebTestBaseTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/CssSelectWebTestBaseTest.php
new file mode 100644
index 0000000..4072ac8
--- /dev/null
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/CssSelectWebTestBaseTest.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Definition of \Drupal\simpletest\Tests\CssSelectWebTestBaseTest.
+ *
+ * Tests cssSelect() when extended from WebTestBase, using $this->content.
+ */
+
+namespace Drupal\simpletest\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+class CssSelectWebTestBaseTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('simpletest');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'SimpleTest css selection',
+      'description' => "Tests SimpleTest's integration with PHPUnit::cssSelect() used in the context of a web test.",
+      'group' => 'SimpleTest'
+    );
+  }
+
+  /**
+   * Tests the cssSelect() method extended from WebTestBase.
+   */
+  function testCssSelect() {
+    // Construct a simple HTML page with a title and a nested menu.
+    $testpage = <<<HTML
+<html>
+  <body>
+    <h1 id="page-title">Title</h1>
+    <ul>
+      <li><a href="link1" class="menu-link first">link 1</a></li>
+      <li>
+        <ul>
+          <li><a href="link2" class="menu-link">link 2</a></li>
+          <li><a href="link3" class="menu-link">link 3</a></li>
+        </ul>
+      </li>
+      <li><a href="link4" class="menu-link last">link 4</a></li>
+    </ul>
+  </body>
+</html>
+HTML;
+    $this->drupalSetContent($testpage);
+
+    // Check that we can reuse the output of cssSelect() to drill deeper.
+    $elements = $this->cssSelect('a.menu-link');
+    $this->assertEqual(count($elements), 4, 'All 4 menu links in the example HTML were found.');
+    $this->assertEqual(get_class($elements[0]), 'DOMElement', 'An array of DOMElement objects was returned.');
+    $elements = $this->cssSelect('.last', TRUE, $elements);
+    $this->assertEqual(count($elements), 1, 'An element matching a class was found when an array of DOMElement objects was passed to cssSelect.');
+
+    // Check that the returned DOMElement contains correct HTML.
+    $elements = $this->cssSelect('#page-title');
+    $this->assertEqual(count($elements), 1, 'The page title in the example HTML was found.');
+    $domelement = reset($elements);
+    $this->assertEqual(get_class($domelement), 'DOMElement', 'A DOMElement object was returned.');
+    $html = '<h1 id="page-title">Title</h1>';
+    $this->assertEqual($domelement->ownerDocument->saveHtml($domelement), $html, 'The DOMElement representing the page title contains the expected HTML.');
+  }
+
+}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestUnitTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestUnitTest.php
new file mode 100644
index 0000000..12f80bd
--- /dev/null
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestUnitTest.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\simpletest\Tests\SimpleTestUnitTest.
+ */
+
+namespace Drupal\simpletest\Tests;
+
+use Drupal\simpletest\UnitTestBase;
+
+/**
+ * Tests the TestBase object.
+ */
+class SimpleTestUnitTest extends UnitTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'SimpleTest unit tests',
+      'description' => 'Unit tests for SimpleTest methods.',
+      'group' => 'SimpleTest'
+    );
+  }
+
+  /**
+   * Tests the cssSelect method.
+   *
+   * @see \PHPUnit_Util_XML::cssSelect()
+   */
+  public function testCssSelect() {
+    $content = <<<HTML
+<div>empty 1</div>
+<div id="test_id" class="my_test_class">
+  <p id="test_child_id">
+    <span id="test_subchild_id">My Subchild</span>
+    My Child
+  </p>
+
+  Test Id Text
+</div>
+<div class="item">classy</div>';
+HTML;
+
+    $elements = $this->cssSelect('div', TRUE, $content);
+    $this->assertEqual(count($elements), 3, 'A selector matching 3 div elements returns 3 results.');
+
+    $elements = $this->cssSelect('#test_id', TRUE, $content);
+    $this->assertEqual(count($elements), 1, 'A selector matching an existing ID returns a result.');
+
+    $elements = $this->cssSelect('p', 'My Subchild My Child', $content);
+    $this->assertEqual(count($elements), 1, 'An element, filtered on text, is found.');
+
+    $elements = $this->cssSelect('#test_subchild_id', 'My Subchild', $content);
+    $this->assertEqual(count($elements), 1, 'An element with a specific ID, filtered on text, is found.');
+
+    $elements = $this->cssSelect('#test_subchild_id', 'Wrong text', $content);
+    $this->assertEqual(count($elements), 0, 'An ID selector, filtered on non-existing text, returns nothing.');
+
+    $elements = $this->cssSelect('div p', TRUE, $content);
+    $this->assertEqual(count($elements), 1, 'A nested selector is found.');
+
+    $elements = $this->cssSelect('p > span', TRUE, $content);
+    $this->assertEqual(count($elements), 1, 'A nested immediate child selector is found.');
+
+    $elements = $this->cssSelect('div > span', TRUE, $content);
+    $this->assertEqual(count($elements), 0, 'A non-existing nested immediate child selector returns nothing.');
+
+    $elements = $this->cssSelect('div span p', TRUE, $content);
+    $this->assertEqual(count($elements), 0, 'A nested selector with elements in the wrong order returns nothing.');
+
+    $elements = $this->cssSelect('div.item', 'classy', $content);
+    $this->assertEqual(count($elements), 1, 'Element with class is found.');
+
+    $elements = $this->cssSelect('span.item', 'classy', $content);
+    $this->assertEqual(count($elements), 0, 'A selector targeting an element with a non-existing class returns nothing.');
+
+    $elements = $this->cssSelect('#non-existing-id', TRUE, $content);
+    $this->assertTrue(is_array($elements) && !count($elements), 'The cssSelect() method returns an empty array when no match was found.');
+  }
+
+}
diff --git a/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php b/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php
index dcadd3f..04c33f4 100644
--- a/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php
+++ b/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php
@@ -42,31 +42,21 @@ protected function setUp() {
   public function testTourFunctionality() {
     // Navigate to tour-test-1 and verify the tour_test_1 tip is found with appropriate classes.
     $this->drupalGet('tour-test-1');
-    $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', array(
-      ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1 even last',
-      ':data_id' => 'tour-test-1',
-      ':text' => 'The first tip',
-    ));
+    $elements = $this->cssSelect('h2', 'The first tip', $this->cssSelect("li.tip-module-tour-test.tip-type-text.tip-tour-test-1.even.last[data-id=tour-test-1]"));
     $this->assertEqual(count($elements), 1, 'Found English variant of tip 1.');
 
-    $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./p//a[@href=:href and contains(., :text)]]', array(
-      ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1 even last',
-      ':data_id' => 'tour-test-1',
-      ':href' =>  url('<front>', array('absolute' => TRUE)),
-      ':text' => 'Drupal',
-    ));
+    // Check for the token replacements done in <a href="[site:url]">[site:name]</a>
+    $context = $this->cssSelect('li.tip-type-text[data-id=tour-test-1');
+    $context = $this->cssSelect('p', TRUE, $context);
+    $url = url('<front>', array('absolute' => TRUE));
+
+    $elements = $this->cssSelect('a[href=' . $url . ']', 'Drupal', $context);
     $this->assertEqual(count($elements), 1, 'Found Token replacement.');
 
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-test-2',
-      ':text' => 'The quick brown fox',
-    ));
+    $elements = $this->cssSelect('h2', 'The quick brown fox', $this->cssSelect("li[data-id=tour-test-2]"));
     $this->assertNotEqual(count($elements), 1, 'Did not find English variant of tip 2.');
 
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-test-1',
-      ':text' => 'La pioggia cade in spagna',
-    ));
+    $elements = $this->cssSelect('h2', 'La pioggia cade in spagna', $this->cssSelect("li[data-id=tour-test-1]"));
     $this->assertNotEqual(count($elements), 1, 'Did not find Italian variant of tip 1.');
 
     // Ensure that plugin's work.
@@ -74,16 +64,10 @@ public function testTourFunctionality() {
 
     // Navigate to tour-test-2/subpath and verify the tour_test_2 tip is found.
     $this->drupalGet('tour-test-2/subpath');
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-test-2',
-      ':text' => 'The quick brown fox',
-    ));
+    $elements = $this->cssSelect('h2', 'The quick brown fox', $this->cssSelect("li[data-id=tour-test-2]"));
     $this->assertEqual(count($elements), 1, 'Found English variant of tip 2.');
 
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-test-1',
-      ':text' => 'The first tip',
-    ));
+    $elements = $this->cssSelect('h2', 'The first tip', $this->cssSelect("li[data-id=tour-test-1]"));
     $this->assertNotEqual(count($elements), 1, 'Did not find English variant of tip 1.');
 
     // Enable Italian language and navigate to it/tour-test1 and verify italian
@@ -91,16 +75,10 @@ public function testTourFunctionality() {
     language_save(new Language(array('id' => 'it')));
     $this->drupalGet('it/tour-test-1');
 
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-test-1',
-      ':text' => 'La pioggia cade in spagna',
-    ));
+    $elements = $this->cssSelect('h2', 'La pioggia cade in spagna', $this->cssSelect("li[data-id=tour-test-1]"));
     $this->assertEqual(count($elements), 1, 'Found Italian variant of tip 1.');
 
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-test-1',
-      ':text' => 'The first tip',
-    ));
+    $elements = $this->cssSelect('h2', 'The quick brown fox', $this->cssSelect("li[data-id=tour-test-2]"));
     $this->assertNotEqual(count($elements), 1, 'Did not find English variant of tip 1.');
 
     language_save(new Language(array('id' => 'en')));
@@ -138,18 +116,12 @@ public function testTourFunctionality() {
 
     // Navigate to tour-test-1 and verify the new tip is found.
     $this->drupalGet('tour-test-1');
-    $elements = $this->xpath('//li[@data-id=:data_id and ./h2[contains(., :text)]]', array(
-      ':data_id' => 'tour-code-test-1',
-      ':text' => 'The rain in spain',
-    ));
+    $elements = $this->cssSelect('h2', 'The rain in spain', $this->cssSelect("li[data-id=tour-code-test-1]"));
     $this->assertEqual(count($elements), 1, 'Found the required tip markup for tip 4');
 
     // Verify that the weight sorting works by ensuring the lower weight item
     // (tip 4) has the 'End tour' button.
-    $elements = $this->xpath('//li[@data-id=:data_id and @data-text=:text]', array(
-      ':data_id' => 'tour-code-test-1',
-      ':text' => 'End tour',
-    ));
+    $elements = $this->cssSelect("li[data-id=tour-code-test-1][data-text*=End]");
     $this->assertEqual(count($elements), 1, 'Found code tip was weighted last and had "End tour".');
 
     // Test hook_tour_alter().
