Skip to content
Snippets Groups Projects
Commit efc85b5a authored by catch's avatar catch
Browse files

Issue #3000762 by Krzysztof Domański, Hardik_Patel_12, saurabh.tripathi.cs,...

Issue #3000762 by Krzysztof Domański, Hardik_Patel_12, saurabh.tripathi.cs, Lendude, ApacheEx, nnevill, alexpott: Add assertNoDuplicateIds to a functional test trait
parent b17a6986
Branches
Tags
8 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!1012Issue #3226887: Hreflang on non-canonical content pages,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10,!596Issue #3046532: deleting an entity reference field, used in a contextual view, makes the whole site unrecoverable,!496Issue #2463967: Use .user.ini file for PHP settings,!144Issue #2666286: Clean up menu_ui to conform to Drupal coding standards,!16Draft: Resolve #2081585 "History storage",!13Resolve #2903456
......@@ -115,7 +115,7 @@ public function testNodeDisplay() {
$this->assertSession()->responseContains($field_name . '[1][description]', 'Description of second file appears as expected.');
// Check that the file fields don't contain duplicate HTML IDs.
$this->assertNoDuplicateIds();
$this->assertSession()->pageContainsNoDuplicateId();
}
/**
......@@ -229,32 +229,4 @@ public function testDescriptionDefaultFileFieldDisplay() {
$this->assertFieldByXPath('//a[@href="' . $node->{$field_name}->entity->createFileUrl(FALSE) . '"]', $description);
}
/**
* Asserts that each HTML ID is used for just a single element on the page.
*
* @param string $message
* (optional) A message to display with the assertion.
*/
protected function assertNoDuplicateIds($message = '') {
$args = ['@url' => $this->getUrl()];
if (!$elements = $this->xpath('//*[@id]')) {
$this->fail(new FormattableMarkup('The page @url contains no HTML IDs.', $args));
return;
}
$message = $message ?: new FormattableMarkup('The page @url does not contain duplicate HTML IDs', $args);
$seen_ids = [];
foreach ($elements as $element) {
$id = $element->getAttribute('id');
if (isset($seen_ids[$id])) {
$this->fail($message);
return;
}
$seen_ids[$id] = TRUE;
}
$this->assertTrue(TRUE, $message);
}
}
......@@ -155,6 +155,56 @@ public function metaRefresh() {
return new RedirectResponse(Url::fromRoute('test_page_test.test_page', [], ['absolute' => TRUE])->toString(), 302);
}
/**
* Returns a page render array with 2 elements with the same HTML IDs.
*
* @return array
* A render array as expected by
* \Drupal\Core\Render\RendererInterface::render().
*/
public function renderPageWithDuplicateIds() {
return [
'#type' => 'container',
'title' => [
'#type' => 'html_tag',
'#tag' => 'h1',
'#value' => 'Hello',
'#attributes' => ['id' => 'page-element'],
],
'description' => [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => 'World',
'#attributes' => ['id' => 'page-element'],
],
];
}
/**
* Returns a page render array with 2 elements with the unique HTML IDs.
*
* @return array
* A render array as expected by
* \Drupal\Core\Render\RendererInterface::render().
*/
public function renderPageWithoutDuplicateIds() {
return [
'#type' => 'container',
'title' => [
'#type' => 'html_tag',
'#tag' => 'h1',
'#value' => 'Hello',
'#attributes' => ['id' => 'page-element-title'],
],
'description' => [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => 'World',
'#attributes' => ['id' => 'page-element-description'],
],
];
}
/**
* Returns a page while triggering deprecation notices.
*/
......
......@@ -115,6 +115,20 @@ test_page_test.meta_refresh:
requirements:
_access: 'TRUE'
test_page_test.page_with_duplicate_ids:
path: '/test-page-with-duplicate-ids'
defaults:
_controller: '\Drupal\test_page_test\Controller\Test::renderPageWithDuplicateIds'
requirements:
_access: 'TRUE'
test_page_test.page_without_duplicate_ids:
path: '/test-page-without-duplicate-ids'
defaults:
_controller: '\Drupal\test_page_test\Controller\Test::renderPageWithoutDuplicateIds'
requirements:
_access: 'TRUE'
test_page_test.deprecations:
path: '/test-deprecations'
defaults:
......
......@@ -2,7 +2,6 @@
namespace Drupal\FunctionalJavascriptTests\Ajax;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
......@@ -88,7 +87,7 @@ public function testMultiForm() {
$this->assertFieldsByValue($field->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button on the initial page.');
}
$this->assertNoDuplicateIds();
$this->assertSession()->pageContainsNoDuplicateId();
// Submit the "add more" button of each form twice. After each corresponding
// page update, ensure the same as above.
......@@ -108,37 +107,9 @@ public function testMultiForm() {
$field = $page_updated->findAll('xpath', '.' . $field_xpath);
$this->assertCount($i + 2, $field[0]->find('xpath', '.' . $field_items_xpath_suffix), 'Found the correct number of field items after an AJAX submission.');
$this->assertFieldsByValue($field[0]->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button after an AJAX submission.');
$this->assertNoDuplicateIds();
$this->assertSession()->pageContainsNoDuplicateId();
}
}
}
/**
* Asserts that each HTML ID is used for just a single element on the page.
*
* @param string $message
* (optional) A message to display with the assertion.
*/
protected function assertNoDuplicateIds($message = '') {
$args = ['@url' => $this->getUrl()];
if (!$elements = $this->xpath('//*[@id]')) {
$this->fail(new FormattableMarkup('The page @url contains no HTML IDs.', $args));
return;
}
$message = $message ?: new FormattableMarkup('The page @url does not contain duplicate HTML IDs', $args);
$seen_ids = [];
foreach ($elements as $element) {
$id = $element->getAttribute('id');
if (isset($seen_ids[$id])) {
$this->fail($message);
return;
}
$seen_ids[$id] = TRUE;
}
$this->assertTrue(TRUE, $message);
}
}
......@@ -770,6 +770,22 @@ public function testHtkey() {
$this->assertSession()->statusCodeEquals(403);
}
/**
* Tests pageContainsNoDuplicateId() functionality.
*
* @see \Drupal\Tests\WebAssert::pageContainsNoDuplicateId()
*/
public function testPageContainsNoDuplicateId() {
$assert_session = $this->assertSession();
$this->drupalGet(Url::fromRoute('test_page_test.page_without_duplicate_ids'));
$assert_session->pageContainsNoDuplicateId();
$this->drupalGet(Url::fromRoute('test_page_test.page_with_duplicate_ids'));
$this->expectException(ExpectationException::class);
$this->expectExceptionMessage('The page contains a duplicate HTML ID "page-element".');
$assert_session->pageContainsNoDuplicateId();
}
/**
* Tests assertEscaped() and assertUnescaped().
*
......
......@@ -626,4 +626,20 @@ public function pageTextContainsOnce($text) {
throw new ResponseTextException($message, $this->session->getDriver());
}
/**
* Asserts that each HTML ID is used for just a single element on the page.
*
* @throws \Behat\Mink\Exception\ExpectationException
*/
public function pageContainsNoDuplicateId() {
$seen_ids = [];
foreach ($this->session->getPage()->findAll('xpath', '//*[@id]') as $element) {
$id = $element->getAttribute('id');
if (isset($seen_ids[$id])) {
throw new ExpectationException(sprintf('The page contains a duplicate HTML ID "%s".', $id), $this->session->getDriver());
}
$seen_ids[$id] = TRUE;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment