diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index 4780e85..2c0e0f2 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -1309,4 +1309,42 @@ 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 (HTML tag normally) of the page.
+ *
+ * @param string $selector
+ * CSS selector to use in the search.
+ * @param string $contains
+ * (optional) Filter matching nodes to those containing the given 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) Context to parse for selector. 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/SimpleTestUnitTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestUnitTest.php
new file mode 100644
index 0000000..8af5204
--- /dev/null
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestUnitTest.php
@@ -0,0 +1,73 @@
+ 'SimpleTest functionality (Unit test)',
+ 'description' => "Tests some methods of Simpletest as unit test.",
+ 'group' => 'SimpleTest'
+ );
+ }
+
+ /**
+ * Tests the cssSelect method.
+ *
+ * @see \PHPUnit_Util_XML::cssSelect()
+ */
+ public function testCssSelect() {
+ $content = '
empty 1
+
+
+ My Subchild
+ My Child
+
+
+ Test Id Text
+
+ classy
';
+
+ $root = $this->cssSelect('div', TRUE, $content);
+ $this->assertEqual(count($root), 3, '3 divs found');
+
+ $root = $this->cssSelect('#test_id', TRUE, $content);
+ $this->assertEqual(count($root), 1, 'ID selector works');
+
+ $child = $this->cssSelect('p', 'My Subchild My Child', $content);
+ $this->assertEqual(count($child), 1, 'Text content found.');
+
+ $child = $this->cssSelect('#test_subchild_id', 'My Subchild', $content);
+ $this->assertEqual(count($child), 1, 'Text match found.');
+
+ $child = $this->cssSelect('#test_subchild_id', 'Wrong text', $content);
+ $this->assertEqual(count($child), 0, 'Text match not found');
+
+ $child = $this->cssSelect('div p', TRUE, $content);
+ $this->assertEqual(count($child), 1, 'Nested selector');
+
+ $child = $this->cssSelect('div > span', TRUE, $content);
+ $this->assertEqual(count($child), 0, 'Nested immediate child selector.');
+
+ $child = $this->cssSelect('div span p', TRUE, $content);
+ $this->assertEqual(count($child), 0, 'Nested selector wrong order');
+
+ $child = $this->cssSelect('div.item', 'classy', $content);
+ $this->assertEqual(count($child), 1, 'Element with class');
+
+ $child = $this->cssSelect('span.item', 'classy', $content);
+ $this->assertEqual(count($child), 0, 'Element with class');
+ }
+
+}
diff --git a/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php b/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php
index dcadd3f..bd8d70d 100644
--- a/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php
+++ b/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php
@@ -8,12 +8,12 @@
namespace Drupal\tour\Tests;
use Drupal\Core\Language\Language;
-use Drupal\simpletest\WebTestBase;
+use Drupal\tour\Tests\TourTestBase;
/**
* Tests tour functionality.
*/
-class TourTest extends WebTestBase {
+class TourTest extends TourTestBase {
/**
* Modules to enable.
@@ -42,31 +42,22 @@ 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.');
+ $this->assertTourTips();
- $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('', array('absolute' => TRUE)),
- ':text' => 'Drupal',
- ));
+ // Check for the token replacements done in [site:name]
+ $context = $this->cssSelect('li.tip-type-text[data-id=tour-test-1');
+ $context = $this->cssSelect('p', TRUE, $context);
+ $url = url('', 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 +65,11 @@ 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.');
+ $this->assertTourTips();
- $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 +77,11 @@ 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.');
+ $this->assertTourTips();
- $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.');
language_save(new Language(array('id' => 'en')));
@@ -138,18 +119,13 @@ 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');
+ $this->assertTourTips();
// 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().
diff --git a/core/modules/tour/lib/Drupal/tour/Tests/TourTestBase.php b/core/modules/tour/lib/Drupal/tour/Tests/TourTestBase.php
new file mode 100644
index 0000000..fa72750
--- /dev/null
+++ b/core/modules/tour/lib/Drupal/tour/Tests/TourTestBase.php
@@ -0,0 +1,63 @@
+assertTourTips();
+ *
+ * Advanced xample:
+ * $tips = array();
+ * $tips[] = array('data-id' => 'foo');
+ * $tips[] = array('data-id' => 'bar');
+ * $tips[] = array('data-class' => 'baz');
+ * $this->assertTourTips($tips);
+ */
+ public function assertTourTips($tips = array()) {
+ // Using xpath, get the rendered tips and there data-id and data-class attributes.
+ if (empty($tips)) {
+ $rendered_tips = $this->xpath('//ol[@id = "tour"]//li');
+ foreach ($rendered_tips as $rendered_tip) {
+ $attributes = (array) $rendered_tip->attributes();
+ $tips[] = $attributes['@attributes'];
+ }
+ }
+
+ // If the tips are still empty we need to fail.
+ if (empty($tips)) {
+ $this->assertTrue(FALSE, 'Could not find tour tips on the current page.');
+ return;
+ }
+
+ // Check for corresponding page elements.
+ foreach ($tips as $tip) {
+ if (!empty($tip['data-id'])) {
+ $elements = $this->cssSelect('#' . $tip['data-id']);
+ $this->assertTrue(count($elements), format_string('Found corresponding page element for tour tip with id #%data-id', array('%data-id' => $tip['data-id'])));
+ }
+ else if (!empty($tip['data-class'])) {
+ $elements = $this->cssSelect('.' . $tip['data-class']);
+ $this->assertTrue(count($elements), format_string('Found corresponding page element for tour tip with class .%data-class', array('%data-class' => $tip['data-class'])));
+ }
+ }
+ }
+
+}
diff --git a/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php b/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php
index 73b7cde..62aa705 100644
--- a/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php
+++ b/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php
@@ -33,6 +33,13 @@ public function tourTest1() {
),
'#children' => t('Where does the rain in Spain fail?'),
),
+ 'tip-3' => array(
+ '#type' => 'container',
+ '#attributes' => array(
+ 'id' => 'tour-test-3',
+ ),
+ '#children' => t('Tip created now?'),
+ ),
'tip-4' => array(
'#type' => 'container',
'#attributes' => array(
@@ -40,6 +47,13 @@ public function tourTest1() {
),
'#children' => t('Tip created later?'),
),
+ 'code-tip-1' => array(
+ '#type' => 'container',
+ '#attributes' => array(
+ 'id' => 'tour-code-test-1',
+ ),
+ '#children' => t('Tip created now?'),
+ ),
);
}
diff --git a/core/modules/views_ui/config/tour.tour.views-ui.yml b/core/modules/views_ui/config/tour.tour.views-ui.yml
index 6f2ca9d..cbd3605 100644
--- a/core/modules/views_ui/config/tour.tour.views-ui.yml
+++ b/core/modules/views_ui/config/tour.tour.views-ui.yml
@@ -3,7 +3,7 @@ module: views_ui
label: Views ui
langcode: en
paths:
- - admin/structure/views/view/*/edit
+ - admin/structure/views/view/*
tips:
views-ui-active-display:
id: views-ui-active-display
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Tests/TourTips.php b/core/modules/views_ui/lib/Drupal/views_ui/Tests/TourTips.php
new file mode 100644
index 0000000..307077f
--- /dev/null
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Tests/TourTips.php
@@ -0,0 +1,60 @@
+ 'Tour tips',
+ 'description' => 'Tests the views ui tour functionality.',
+ 'group' => 'Views UI',
+ );
+ }
+
+ protected function setUp() {
+ parent::setUp();
+ $this->adminUser = $this->drupalCreateUser(array('administer views', 'access tour'));
+ $this->drupalLogin($this->adminUser);
+ }
+
+ /**
+ * Tests views_ui tour tip availability.
+ */
+ public function testViewsUiTourTips() {
+ // Create a basic view that shows all content, with a page and a block
+ // display.
+ $view['label'] = $this->randomName(16);
+ $view['id'] = strtolower($this->randomName(16));
+ $view['page[create]'] = 1;
+ $view['page[path]'] = $this->randomName(16);
+ $view_path = $view['page[path]'];
+ $this->drupalPost('admin/structure/views/add', $view, t('Save and edit'));
+ $this->assertTourTips();
+ }
+
+}