diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php index c42d988..9ab9ec7 100644 --- a/core/modules/comment/src/Tests/CommentTestBase.php +++ b/core/modules/comment/src/Tests/CommentTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\comment\Tests; +@trigger_error('\Drupal\comment\Tests\CommentTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\comment\Functional\CommentTestBase', E_USER_DEPRECATED); + use Drupal\comment\Entity\CommentType; use Drupal\comment\Entity\Comment; use Drupal\comment\CommentInterface; @@ -12,6 +14,9 @@ /** * Provides setup and helper methods for comment tests. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\comment\Functional\CommentTestBase instead. */ abstract class CommentTestBase extends WebTestBase { diff --git a/core/modules/comment/src/Tests/Views/CommentTestBase.php b/core/modules/comment/src/Tests/Views/CommentTestBase.php index d7bec04..2b3ae1d 100644 --- a/core/modules/comment/src/Tests/Views/CommentTestBase.php +++ b/core/modules/comment/src/Tests/Views/CommentTestBase.php @@ -2,13 +2,17 @@ namespace Drupal\comment\Tests\Views; +@trigger_error('\Drupal\comment\Tests\Views\CommentTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\comment\Functional\Views\CommentTestBase', E_USER_DEPRECATED); + use Drupal\comment\Tests\CommentTestTrait; -use Drupal\views\Tests\ViewTestBase; use Drupal\views\Tests\ViewTestData; use Drupal\comment\Entity\Comment; /** * Tests the argument_comment_user_uid handler. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\comment\Functional\Views\CommentTestBase instead. */ abstract class CommentTestBase extends ViewTestBase { diff --git a/core/modules/comment/src/Tests/CommentActionsTest.php b/core/modules/comment/tests/src/Functional/CommentActionsTest.php similarity index 97% rename from core/modules/comment/src/Tests/CommentActionsTest.php rename to core/modules/comment/tests/src/Functional/CommentActionsTest.php index 56d34e4..79786fc 100644 --- a/core/modules/comment/src/Tests/CommentActionsTest.php +++ b/core/modules/comment/tests/src/Functional/CommentActionsTest.php @@ -1,6 +1,6 @@ drupalPostForm(NULL, $edit, t('Update')); $this->assertText(t('Are you sure you want to delete these comments and all their children?'), 'Confirmation required.'); - $this->drupalPostForm(NULL, $edit, t('Delete comments')); + $this->drupalPostForm(NULL, [], t('Delete comments')); $this->assertText(t('No comments available.'), 'All comments were deleted.'); // Test message when no comments selected. $edit = [ diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/tests/src/Functional/CommentAnonymousTest.php similarity index 97% rename from core/modules/comment/src/Tests/CommentAnonymousTest.php rename to core/modules/comment/tests/src/Functional/CommentAnonymousTest.php index d60c073..3f294c0 100644 --- a/core/modules/comment/src/Tests/CommentAnonymousTest.php +++ b/core/modules/comment/tests/src/Functional/CommentAnonymousTest.php @@ -1,6 +1,6 @@ drupalPostForm($this->node->urlInfo(), $edit, t('Preview')); // Cannot use assertRaw here since both title and body are in the form. - $preview = (string) $this->cssSelect('.preview')[0]->asXML(); + $preview = (string) $this->getSession()->getPage()->find('css', '.preview')->getHtml(); $this->assertTrue(strpos($preview, $title) !== FALSE, 'Anonymous user can preview comment title.'); $this->assertTrue(strpos($preview, $body) !== FALSE, 'Anonymous user can preview comment body.'); @@ -56,7 +56,7 @@ public function testAnonymous() { $edit['comment_body[0][value]'] = $body; $this->drupalPostForm($this->node->urlInfo(), $edit, t('Preview')); // Cannot use assertRaw here since both title and body are in the form. - $preview = (string) $this->cssSelect('.preview')[0]->asXML(); + $preview = (string) $this->getSession()->getPage()->find('css', '.preview')->getHtml(); $this->assertTrue(strpos($preview, $title) !== FALSE, 'Anonymous user can preview comment title.'); $this->assertTrue(strpos($preview, $body) !== FALSE, 'Anonymous user can preview comment body.'); user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['skip comment approval']); diff --git a/core/modules/comment/src/Tests/CommentBlockTest.php b/core/modules/comment/tests/src/Functional/CommentBlockTest.php similarity index 98% rename from core/modules/comment/src/Tests/CommentBlockTest.php rename to core/modules/comment/tests/src/Functional/CommentBlockTest.php index 37cc5de..db7d1bd 100644 --- a/core/modules/comment/src/Tests/CommentBlockTest.php +++ b/core/modules/comment/tests/src/Functional/CommentBlockTest.php @@ -1,6 +1,6 @@ drupalGet($this->node->urlInfo()); $element = $this->cssSelect('article.js-comment > div'); // Get last child element. - $element = end($element[0]); - $this->assertIdentical($element[0]->getName(), 'div', 'Last element is comment body.'); + $element = end($element); + $this->assertIdentical($element->getTagName(), 'div', 'Last element is comment body.'); // Change weight to make links go after comment body. entity_get_display('comment', 'comment', 'default') @@ -118,8 +118,8 @@ public function testCommentLinks() { $this->drupalGet($this->node->urlInfo()); $element = $this->cssSelect('article.js-comment > div'); // Get last child element. - $element = end($element[0]); - $this->assertIdentical($element[0]->getName(), 'ul', 'Last element is comment links.'); + $element = end($element); + $this->assertNotEmpty($element->find('css', 'ul.links'), 'Last element is comment links.'); // Make sure we can hide node links. entity_get_display('node', $this->node->bundle(), 'default') diff --git a/core/modules/comment/src/Tests/CommentNewIndicatorTest.php b/core/modules/comment/tests/src/Functional/CommentNewIndicatorTest.php similarity index 99% rename from core/modules/comment/src/Tests/CommentNewIndicatorTest.php rename to core/modules/comment/tests/src/Functional/CommentNewIndicatorTest.php index 55609e3..a93bd1c 100644 --- a/core/modules/comment/src/Tests/CommentNewIndicatorTest.php +++ b/core/modules/comment/tests/src/Functional/CommentNewIndicatorTest.php @@ -1,6 +1,6 @@ drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; - $this->assertEqual(current($this->xpath($xpath)), $this->entity->label(), 'Last breadcrumb item is equal to node title on comment reply page.'); + $this->assertEqual(current($this->xpath($xpath))->getText(), $this->entity->label(), 'Last breadcrumb item is equal to node title on comment reply page.'); // Post a comment. /** @var \Drupal\comment\CommentInterface $comment1 */ @@ -283,17 +283,17 @@ public function testCommentFunctionality() { // Test breadcrumb on comment reply page. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment/' . $comment1->id()); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; - $this->assertEqual(current($this->xpath($xpath)), $comment1->getSubject(), 'Last breadcrumb item is equal to comment title on comment reply page.'); + $this->assertEqual(current($this->xpath($xpath))->getText(), $comment1->getSubject(), 'Last breadcrumb item is equal to comment title on comment reply page.'); // Test breadcrumb on comment edit page. $this->drupalGet('comment/' . $comment1->id() . '/edit'); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; - $this->assertEqual(current($this->xpath($xpath)), $comment1->getSubject(), 'Last breadcrumb item is equal to comment subject on edit page.'); + $this->assertEqual(current($this->xpath($xpath))->getText(), $comment1->getSubject(), 'Last breadcrumb item is equal to comment subject on edit page.'); // Test breadcrumb on comment delete page. $this->drupalGet('comment/' . $comment1->id() . '/delete'); $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; - $this->assertEqual(current($this->xpath($xpath)), $comment1->getSubject(), 'Last breadcrumb item is equal to comment subject on delete confirm page.'); + $this->assertEqual(current($this->xpath($xpath))->getText(), $comment1->getSubject(), 'Last breadcrumb item is equal to comment subject on delete confirm page.'); // Unpublish the comment. $this->performCommentOperation($comment1, 'unpublish'); diff --git a/core/modules/comment/src/Tests/CommentPagerTest.php b/core/modules/comment/tests/src/Functional/CommentPagerTest.php similarity index 99% rename from core/modules/comment/src/Tests/CommentPagerTest.php rename to core/modules/comment/tests/src/Functional/CommentPagerTest.php index 9c48978..bf26aa1 100644 --- a/core/modules/comment/src/Tests/CommentPagerTest.php +++ b/core/modules/comment/tests/src/Functional/CommentPagerTest.php @@ -1,6 +1,6 @@ cssSelect('.comment-wrapper ' . ($reply ? '.indented ' : '') . '#comment-' . $comment->id() . ' ~ article'); + $comment_element = $this->getSession()->getPage()->find('css', '.comment-wrapper ' . ($reply ? '.indented ' : '') . '#comment-' . $comment->id() . ' ~ article'); if (empty($comment_element)) { return FALSE; } - $comment_title = $comment_element[0]->xpath('div/h3/a'); - if (empty($comment_title) || ((string)$comment_title[0]) !== $comment->getSubject()) { + $comment_title = $comment_element->find('xpath', 'div/h3/a'); + if (empty($comment_title) || $comment_title->getText() !== $comment->getSubject()) { return FALSE; } - $comment_body = $comment_element[0]->xpath('div/div/p'); - if (empty($comment_body) || ((string)$comment_body[0]) !== $comment->comment_body->value) { + $comment_body = $comment_element->find('xpath', 'div/div/p'); + if (empty($comment_body) || $comment_body->getText() !== $comment->comment_body->value) { return FALSE; } diff --git a/core/modules/comment/src/Tests/CommentThreadingTest.php b/core/modules/comment/tests/src/Functional/CommentThreadingTest.php similarity index 99% rename from core/modules/comment/src/Tests/CommentThreadingTest.php rename to core/modules/comment/tests/src/Functional/CommentThreadingTest.php index 8f412b2..cff22ba 100644 --- a/core/modules/comment/src/Tests/CommentThreadingTest.php +++ b/core/modules/comment/tests/src/Functional/CommentThreadingTest.php @@ -1,6 +1,6 @@ assertPattern('|]*>]*>' . $subject_text . '|', 'Comment title is rendered in h3 when title populated.'); // Tests that the comment's title link is the permalink of the comment. - $comment_permalink = $this->cssSelect('.permalink'); - $comment_permalink = (string) $comment_permalink[0]['href']; + $comment_permalink = $this->getSession()->getPage()->find('css', '.permalink'); + $comment_permalink = $comment_permalink->getAttribute('href'); // Tests that the comment's title link contains the url fragment. $this->assertTrue(strpos($comment_permalink, '#comment-' . $comment1->id()), "The comment's title link contains the url fragment."); $this->assertEqual($comment1->permalink()->toString(), $comment_permalink, "The comment's title has the correct link."); diff --git a/core/modules/comment/src/Tests/CommentTokenReplaceTest.php b/core/modules/comment/tests/src/Functional/CommentTokenReplaceTest.php similarity index 99% rename from core/modules/comment/src/Tests/CommentTokenReplaceTest.php rename to core/modules/comment/tests/src/Functional/CommentTokenReplaceTest.php index 6caea17..a7fe6b5 100644 --- a/core/modules/comment/src/Tests/CommentTokenReplaceTest.php +++ b/core/modules/comment/tests/src/Functional/CommentTokenReplaceTest.php @@ -1,6 +1,6 @@ drupalLogin($this->drupalCreateUser(['access comments'])); // Add two new languages. diff --git a/core/modules/comment/src/Tests/Views/CommentFieldNameTest.php b/core/modules/comment/tests/src/Functional/Views/CommentFieldNameTest.php similarity index 94% rename from core/modules/comment/src/Tests/Views/CommentFieldNameTest.php rename to core/modules/comment/tests/src/Functional/Views/CommentFieldNameTest.php index 870a4f4..86c9437 100644 --- a/core/modules/comment/src/Tests/Views/CommentFieldNameTest.php +++ b/core/modules/comment/tests/src/Functional/Views/CommentFieldNameTest.php @@ -1,6 +1,6 @@ addDefaultCommentField('node', 'page', $this->fieldName); $this->customComment = Comment::create([ 'entity_id' => $this->nodeUserCommented->id(), diff --git a/core/modules/comment/src/Tests/Views/CommentOperationsTest.php b/core/modules/comment/tests/src/Functional/Views/CommentOperationsTest.php similarity index 94% rename from core/modules/comment/src/Tests/Views/CommentOperationsTest.php rename to core/modules/comment/tests/src/Functional/Views/CommentOperationsTest.php index 89dc364..4bef37e 100644 --- a/core/modules/comment/src/Tests/Views/CommentOperationsTest.php +++ b/core/modules/comment/tests/src/Functional/Views/CommentOperationsTest.php @@ -1,6 +1,6 @@ 0, @@ -51,7 +51,7 @@ protected function setUp() { * Test comment row. */ public function testCommentRestExport() { - $this->drupalGetWithFormat(sprintf('node/%d/comments', $this->nodeUserCommented->id()), 'hal_json'); + $this->drupalGet(sprintf('node/%d/comments', $this->nodeUserCommented->id()), ['query' => ['_format' => 'hal_json']]); $this->assertResponse(200); $contents = Json::decode($this->getRawContent()); $this->assertEqual($contents[0]['subject'], 'How much wood would a woodchuck chuck'); diff --git a/core/modules/comment/src/Tests/Views/CommentRowTest.php b/core/modules/comment/tests/src/Functional/Views/CommentRowTest.php similarity index 91% rename from core/modules/comment/src/Tests/Views/CommentRowTest.php rename to core/modules/comment/tests/src/Functional/Views/CommentRowTest.php index d73811e..7cf3ef3 100644 --- a/core/modules/comment/src/Tests/Views/CommentRowTest.php +++ b/core/modules/comment/tests/src/Functional/Views/CommentRowTest.php @@ -1,6 +1,6 @@ drupalCreateContentType(); diff --git a/core/modules/comment/src/Tests/Views/FilterUserUIDTest.php b/core/modules/comment/tests/src/Functional/Views/FilterUserUIDTest.php similarity index 96% rename from core/modules/comment/src/Tests/Views/FilterUserUIDTest.php rename to core/modules/comment/tests/src/Functional/Views/FilterUserUIDTest.php index 442a0e7..719c597 100644 --- a/core/modules/comment/src/Tests/Views/FilterUserUIDTest.php +++ b/core/modules/comment/tests/src/Functional/Views/FilterUserUIDTest.php @@ -1,6 +1,6 @@ $this->t('Save'), ]; + $form['duplicate_button'] = [ + '#type' => 'submit', + '#name' => 'duplicate_button', + '#value' => 'Duplicate button 1', + ]; + + $form['duplicate_button_2'] = [ + '#type' => 'submit', + '#name' => 'duplicate_button', + '#value' => 'Duplicate button 2', + ]; + return $form; } diff --git a/core/modules/views/tests/src/Functional/ViewTestBase.php b/core/modules/views/tests/src/Functional/ViewTestBase.php new file mode 100644 index 0000000..0465f96 --- /dev/null +++ b/core/modules/views/tests/src/Functional/ViewTestBase.php @@ -0,0 +1,158 @@ +set('views_test_data_schema', $this->schemaDefinition()); + \Drupal::state()->set('views_test_data_views_data', $this->viewsData()); + + \Drupal::service('module_installer')->install(['views_test_data']); + $this->resetAll(); + $this->rebuildContainer(); + $this->container->get('module_handler')->reload(); + + // Load the test dataset. + $data_set = $this->dataSet(); + $query = db_insert('views_test_data') + ->fields(array_keys($data_set[0])); + foreach ($data_set as $record) { + $query->values($record); + } + $query->execute(); + } + + /** + * Orders a nested array containing a result set based on a given column. + * + * @param array $result_set + * An array of rows from a result set, with each row as an associative + * array keyed by column name. + * @param string $column + * The column name by which to sort the result set. + * @param bool $reverse + * (optional) Boolean indicating whether to sort the result set in reverse + * order. Defaults to FALSE. + * + * @return array + * The sorted result set. + */ + protected function orderResultSet($result_set, $column, $reverse = FALSE) { + $order = $reverse ? -1 : 1; + usort($result_set, function ($a, $b) use ($column, $order) { + if ($a[$column] == $b[$column]) { + return 0; + } + return $order * (($a[$column] < $b[$column]) ? -1 : 1); + }); + return $result_set; + } + + /** + * Asserts the existence of a button with a certain ID and label. + * + * @param string $id + * The HTML ID of the button + * @param string $expected_label + * The expected label for the button. + * @param string $message + * (optional) A custom message to display with the assertion. If no custom + * message is provided, the message will indicate the button label. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + */ + protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') { + $xpath = $this->assertSession()->buildXPathQuery('//button[@id=:value]|//input[@id=:value]', [':value' => $id]); + $field = $this->getSession()->getPage()->find('xpath', $xpath); + + if (empty($field)) { + throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id', $field); + } + + $this->assertEquals($expected_label, $field->getValue()); + } + + /** + * Executes a view with debugging. + * + * @param \Drupal\views\ViewExecutable $view + * The view object. + * @param array $args + * (optional) An array of the view arguments to use for the view. + */ + protected function executeView(ViewExecutable $view, $args = []) { + // A view does not really work outside of a request scope, due to many + // dependencies like the current user. + $view->setDisplay(); + $view->preExecute($args); + $view->execute(); + $verbose_message = '
Executed view: ' . ((string) $view->build_info['query']) . '
'; + if ($view->build_info['query'] instanceof SelectInterface) { + $verbose_message .= '
Arguments: ' . print_r($view->build_info['query']->getArguments(), TRUE) . '
'; + } + $this->verbose($verbose_message); + } + + /** + * Returns the schema definition. + */ + protected function schemaDefinition() { + return ViewTestData::schemaDefinition(); + } + + /** + * Returns the views data definition. + */ + protected function viewsData() { + return ViewTestData::viewsData(); + } + + /** + * Returns a very simple test dataset. + */ + protected function dataSet() { + return ViewTestData::dataSet(); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php index c88949d..2a6ebee 100644 --- a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php +++ b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php @@ -223,10 +223,7 @@ protected function assertResponse($code) { * $this->assertSession()->fieldValueEquals() instead. */ protected function assertFieldByName($name, $value = NULL) { - $this->assertSession()->fieldExists($name); - if ($value !== NULL) { - $this->assertSession()->fieldValueEquals($name, (string) $value); - } + $this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value); } /** @@ -245,12 +242,7 @@ protected function assertFieldByName($name, $value = NULL) { * $this->assertSession()->fieldValueNotEquals() instead. */ protected function assertNoFieldByName($name, $value = '') { - if ($this->getSession()->getPage()->findField($name) && isset($value)) { - $this->assertSession()->fieldValueNotEquals($name, (string) $value); - } - else { - $this->assertSession()->fieldNotExists($name); - } + $this->assertNoFieldByXPath($this->constructFieldXpath('name', $name), $value); } /** @@ -271,16 +263,7 @@ protected function assertNoFieldByName($name, $value = '') { * $this->assertSession()->fieldValueEquals() instead. */ protected function assertFieldById($id, $value = '') { - $xpath = $this->assertSession()->buildXPathQuery('//textarea[@id=:value]|//input[@id=:value]|//select[@id=:value]', [':value' => $id]); - $field = $this->getSession()->getPage()->find('xpath', $xpath); - - if (empty($field)) { - throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id', $field); - } - - if ($value !== NULL) { - $this->assertEquals($value, $field->getValue()); - } + $this->assertFieldByXPath($this->constructFieldXpath('id', $id), $value); } /** @@ -293,7 +276,7 @@ protected function assertFieldById($id, $value = '') { * Use $this->assertSession()->fieldExists() instead. */ protected function assertField($field) { - $this->assertSession()->fieldExists($field); + $this->assertFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field)); } /** @@ -306,7 +289,7 @@ protected function assertField($field) { * Use $this->assertSession()->fieldNotExists() instead. */ protected function assertNoField($field) { - $this->assertSession()->fieldNotExists($field); + $this->assertNoFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field), NULL); } /** @@ -430,20 +413,7 @@ protected function assertNoLinkByHref($href) { * $this->assertSession()->fieldValueNotEquals() instead. */ protected function assertNoFieldById($id, $value = '') { - $xpath = $this->assertSession()->buildXPathQuery('//textarea[@id=:value]|//input[@id=:value]|//select[@id=:value]', [':value' => $id]); - $field = $this->getSession()->getPage()->find('xpath', $xpath); - - // Return early if the field could not be found as expected. - if ($field === NULL) { - return; - } - - if (!isset($value)) { - throw new ExpectationException(sprintf('Id "%s" appears on this page, but it should not.', $id), $this->getSession()->getDriver()); - } - elseif ($value === $field->getValue()) { - throw new ExpectationException(sprintf('Failed asserting that %s is not equal to %s', $field->getValue(), $value), $this->getSession()->getDriver()); - } + $this->assertNoFieldByXPath($this->constructFieldXpath('id', $id), $value); } /** @@ -564,13 +534,20 @@ protected function assertNoFieldChecked($id) { * (optional) A message to display with the assertion. Do not translate * messages with t(). * + * @throws ExpectationException + * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->xpath() instead and check the values directly in the test. */ protected function assertFieldByXPath($xpath, $value = NULL, $message = '') { - $fields = $this->xpath($xpath); + try { + $fields = $this->xpath($xpath); - $this->assertFieldsByValue($fields, $value, $message); + $this->assertFieldsByValue($fields, $value, $message); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + throw new ExpectationException($e->getMessage(), $this->getSession()->getDriver()); + } } /** @@ -585,25 +562,32 @@ protected function assertFieldByXPath($xpath, $value = NULL, $message = '') { * (optional) A message to display with the assertion. Do not translate * messages with t(). * + * @throws \Behat\Mink\Exception\ExpectationException + * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->xpath() instead and assert that the result is empty. */ protected function assertNoFieldByXPath($xpath, $value = NULL, $message = '') { - $fields = $this->xpath($xpath); - - // If value specified then check array for match. - $found = TRUE; - if (isset($value)) { - $found = FALSE; - if ($fields) { - foreach ($fields as $field) { - if ($field->getAttribute('value') == $value) { - $found = TRUE; + try { + $fields = $this->xpath($xpath); + + // If value specified then check array for match. + $found = TRUE; + if (isset($value)) { + $found = FALSE; + if ($fields) { + foreach ($fields as $field) { + if ($field->getAttribute('value') == $value) { + $found = TRUE; + } } } } + $this->assertFalse($fields && $found, $message); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + throw new ExpectationException($e->getMessage(), $this->getSession()->getDriver()); } - return $this->assertFalse($fields && $found, $message); } /** @@ -637,7 +621,7 @@ protected function assertFieldsByValue($fields, $value = NULL, $message = '') { // Select element with an option. $found = TRUE; } - elseif ($field->getText() == $value) { + elseif ($field->getTagName() !== 'input' && $field->getText() == $value) { // Text area with correct text. $found = TRUE; } @@ -773,6 +757,25 @@ protected function buildXPathQuery($xpath, array $args = []) { } /** + * Helper: Constructs an XPath for the given set of attributes and value. + * + * @param string $attribute + * Field attributes. + * @param string $value + * Value of field. + * + * @return string + * XPath for specified values. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->getSession()->getPage()->findField() instead. + */ + protected function constructFieldXpath($attribute, $value) { + $xpath = '//textarea[@' . $attribute . '=:value]|//input[@' . $attribute . '=:value]|//select[@' . $attribute . '=:value]'; + return $this->buildXPathQuery($xpath, [':value' => $value]); + } + + /** * Gets the current raw content. * * @deprecated Scheduled for removal in Drupal 9.0.0. diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php index 9931804..5e66f86 100644 --- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php @@ -201,13 +201,13 @@ public function testLegacyFieldAsserts() { $this->assertFieldById('edit-name'); $this->fail('The "edit-name" field with no value was found.'); } - catch (\PHPUnit_Framework_ExpectationFailedException $e) { + catch (ExpectationException $e) { $this->pass('The "edit-name" field with no value was not found.'); } - // Test that the assertion fails correctly if NULL is passed in. + // Test that the assertion fails correctly if another value is passed in. try { - $this->assertFieldById('name', NULL); + $this->assertFieldById('edit-name', 'not the value'); $this->fail('The "name" field was found.'); } catch (ExpectationException $e) { @@ -237,6 +237,19 @@ public function testLegacyFieldAsserts() { $this->pass('The "name" field was found.'); } + // Test that multiple fields with the same name are validated correctly. + $this->assertFieldByName('duplicate_button', 'Duplicate button 1'); + $this->assertFieldByName('duplicate_button', 'Duplicate button 2'); + $this->assertNoFieldByName('duplicate_button', 'Rabbit'); + + try { + $this->assertNoFieldByName('duplicate_button', 'Duplicate button 2'); + $this->fail('The "duplicate_button" field with the value Duplicate button 2 was not found.'); + } + catch (ExpectationException $e) { + $this->pass('The "duplicate_button" field with the value Duplicate button 2 was found.'); + } + $this->assertOptionByText('options', 'one'); try { $this->assertOptionByText('options', 'four');