diff --git a/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php b/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php index d8d406b440..94e7812892 100644 --- a/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php +++ b/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php @@ -59,7 +59,7 @@ public function testBookOrdering() { $this->assertGreaterThan($weight_select1->getValue(), $weight_select2->getValue()); // Check that '1st page' precedes the '2nd page'. - $this->assertOrderInPage(['1st page', '2nd page']); + $this->assertSession()->orderInPageText(['1st page', '2nd page']); // Check that the 'unsaved changes' text is not present in the message area. $this->assertSession()->pageTextNotContains('You have unsaved changes.'); @@ -79,7 +79,7 @@ public function testBookOrdering() { $this->assertSession()->pageTextContains('You have unsaved changes.'); // Check that '2nd page' page precedes the '1st page'. - $this->assertOrderInPage(['2nd page', '1st page']); + $this->assertSession()->orderInPageText(['2nd page', '1st page']); $this->submitForm([], 'Save book pages'); $this->assertSession()->pageTextContains(new FormattableMarkup('Updated book @book.', ['@book' => $book->getTitle()])); @@ -90,7 +90,7 @@ public function testBookOrdering() { $this->assertGreaterThan($page2->book['weight'], $page1->book['weight']); // Check again that '2nd page' is on top after form submit in the UI. - $this->assertOrderInPage(['2nd page', '1st page']); + $this->assertSession()->orderInPageText(['2nd page', '1st page']); // Toggle row weight selects as visible. $page->findButton('Show row weights')->click(); @@ -120,7 +120,7 @@ public function testBookOrdering() { $this->assertSession()->pageTextContains(new FormattableMarkup('Updated book @book.', ['@book' => $book->getTitle()])); // Check that the '1st page' is first again. - $this->assertOrderInPage(['1st page', '2nd page']); + $this->assertSession()->orderInPageText(['1st page', '2nd page']); // Check that page reordering was done in the backend for manual weight // field usage. @@ -129,32 +129,4 @@ public function testBookOrdering() { $this->assertGreaterThan($page2->book['weight'], $page1->book['weight']); } - /** - * Asserts that several pieces of markup are in a given order in the page. - * - * @param string[] $items - * An ordered list of strings. - * - * @throws \Behat\Mink\Exception\ExpectationException - * When any of the given string is not found. - * - * @todo Remove this once https://www.drupal.org/node/2817657 is committed. - */ - protected function assertOrderInPage(array $items) { - $session = $this->getSession(); - $text = $session->getPage()->getHtml(); - $strings = []; - foreach ($items as $item) { - if (($pos = strpos($text, $item)) === FALSE) { - throw new ExpectationException("Cannot find '$item' in the page", $session->getDriver()); - } - $strings[$pos] = $item; - } - ksort($strings); - $ordered = implode(', ', array_map(function ($item) { - return "'$item'"; - }, $items)); - $this->assertSame($items, array_values($strings), "Found strings, ordered as: $ordered."); - } - } diff --git a/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php b/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php index 2de84e9593..33f8a8d03e 100644 --- a/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php +++ b/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php @@ -108,4 +108,14 @@ public function renderPipeInLink() { return ['#markup' => 'foo|bar|baz']; } + /** + * Renders a page with strings in a specific order. + * + * @return array + * A render array as expected by drupal_render() + */ + public function renderOrderInPage() { + return ['#markup' => 'item3

item2

item1']; + } + } diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml index 5d84695f8b..8edc37c352 100644 --- a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml +++ b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml @@ -82,3 +82,11 @@ test_page_test.field_xpath: _form: '\Drupal\test_page_test\Form\TestForm' requirements: _access: 'TRUE' + +test_page_test.order_in_page: + path: '/test-order-in-page' + defaults: + _title: 'Page with strings in a given order' + _controller: '\Drupal\test_page_test\Controller\Test::renderOrderInPage' + requirements: + _access: 'TRUE' diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php index 9931804232..0d3c3bf95c 100644 --- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php @@ -2,6 +2,7 @@ namespace Drupal\FunctionalTests; +use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Exception\ExpectationException; use Drupal\Component\Utility\Html; use Drupal\Core\Url; @@ -289,4 +290,19 @@ public function testInstall() { $this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists"); } + /** + * Tests assertion of string sequence in page content and page text. + */ + public function testOrderInPage() { + $this->drupalGet('test-order-in-page'); + + // Check that asserting order in page markup and page works. + $this->assertSession()->orderInPageContent(['item3', 'item1', 'item2']); + $this->assertSession()->orderInPageText(['item3', 'item2', 'item1']); + + // Check that passing non-existent search strings throws an exception. + $this->setExpectedException(ElementNotFoundException::class, "Cannot find item(s): 'item5', 'item8'."); + $this->assertSession()->orderInPageContent(['item5', 'item1', 'item8']); + } + } diff --git a/core/tests/Drupal/Tests/WebAssert.php b/core/tests/Drupal/Tests/WebAssert.php index ea42517818..32f6227822 100644 --- a/core/tests/Drupal/Tests/WebAssert.php +++ b/core/tests/Drupal/Tests/WebAssert.php @@ -501,4 +501,62 @@ public function hiddenFieldValueNotEquals($field, $value, TraversableElement $co $this->assert(!preg_match($regex, $actual), $message); } + /** + * Asserts that several strings are in a given order in the page content. + * + * @param string[] $items + * An ordered list of strings. + */ + public function orderInPageContent(array $items) { + $this->orderInPageHelper($items, $this->session->getPage()->getHtml()); + } + + /** + * Asserts that several strings are in a given order in the page text. + * + * @param string[] $items + * An ordered list of strings. + */ + public function orderInPageText(array $items) { + $this->orderInPageHelper($items, $this->session->getPage()->getText()); + } + + /** + * Provides a helper method for orderInPageText() and orderInPageContent(). + * + * @param string[] $items + * An ordered list of strings. + * @param string $string + * The string to be searched. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * When one or more of passed items are not found. + * + * @see \Drupal\Tests\WebAssert::orderInPageContent() + * @see \Drupal\Tests\WebAssert::orderInPageText() + */ + protected function orderInPageHelper(array $items, $string) { + $strings = $not_found = []; + foreach ($items as $item) { + if (($pos = strpos($string, $item)) === FALSE) { + $not_found[] = "'$item'"; + } + else { + $strings[$pos] = $item; + } + } + + if ($not_found) { + $not_found = implode(', ', $not_found); + throw new ElementNotFoundException($this->session->getDriver(), "Cannot find item(s): $not_found."); + } + + ksort($strings); + $ordered = implode(', ', array_map(function ($item) { + return "'$item'"; + }, $items)); + + $this->assert($items === array_values($strings), "Strings correctly ordered as: $ordered."); + } + }