diff --git a/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php b/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php index 5f25dd7..7da2f03 100644 --- a/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php +++ b/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php @@ -35,6 +35,18 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => 'Test name', ]; + $form['checkbox_enabled'] = [ + '#type' => 'checkbox', + '#title' => 'Checkbox enabled', + '#default_value' => TRUE, + ]; + + $form['checkbox_disabled'] = [ + '#type' => 'checkbox', + '#title' => 'Checkbox disabled', + '#default_value' => FALSE, + ]; + $form['description'] = [ '#type' => 'textfield', '#title' => 'Description', @@ -57,6 +69,18 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#value' => $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/tests/Drupal/FunctionalTests/AssertLegacyTrait.php b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php index c88949d..7092ad9 100644 --- a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php +++ b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php @@ -2,7 +2,6 @@ namespace Drupal\FunctionalTests; -use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Exception\ExpectationException; use Behat\Mink\Selector\Xpath\Escaper; use Drupal\Component\Render\FormattableMarkup; @@ -220,13 +219,11 @@ protected function assertResponse($code) { * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldExists() or + * $this->assertSession()->buttonExists() or * $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); } /** @@ -242,15 +239,11 @@ protected function assertFieldByName($name, $value = NULL) { * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldNotExists() or + * $this->assertSession()->buttonNotExists() or * $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); } /** @@ -268,19 +261,11 @@ protected function assertNoFieldByName($name, $value = '') { * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldExists() or + * $this->assertSession()->buttonExists() or * $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); } /** @@ -290,10 +275,11 @@ protected function assertFieldById($id, $value = '') { * Name or ID of field to assert. * * @deprecated Scheduled for removal in Drupal 9.0.0. - * Use $this->assertSession()->fieldExists() instead. + * Use $this->assertSession()->fieldExists() or + * $this->assertSession()->buttonExists() instead. */ protected function assertField($field) { - $this->assertSession()->fieldExists($field); + $this->assertFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field)); } /** @@ -303,10 +289,11 @@ protected function assertField($field) { * Name or ID of field to assert. * * @deprecated Scheduled for removal in Drupal 9.0.0. - * Use $this->assertSession()->fieldNotExists() instead. + * Use $this->assertSession()->fieldNotExists() or + * $this->assertSession()->buttonNotExists() instead. */ protected function assertNoField($field) { - $this->assertSession()->fieldNotExists($field); + $this->assertNoFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field), NULL); } /** @@ -427,23 +414,11 @@ protected function assertNoLinkByHref($href) { * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldNotExists() or + * $this->assertSession()->buttonNotExists() or * $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); } /** @@ -585,25 +560,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; - } + if (!empty($fields)) { + if (isset($value)) { + $found = FALSE; + try { + $this->assertFieldsByValue($fields, $value); + $found = TRUE; + } + catch (\Exception $e) { + } + + if ($found) { + throw new ExpectationException(sprintf('The field resulting from %s was found with the provided value %s.', $xpath, $value), $this->getSession()->getDriver()); } } + else { + throw new ExpectationException(sprintf('The field resulting from %s was found.', $xpath), $this->getSession()->getDriver()); + } } - return $this->assertFalse($fields && $found, $message); } /** @@ -629,18 +611,23 @@ protected function assertFieldsByValue($fields, $value = NULL, $message = '') { $found = FALSE; if ($fields) { foreach ($fields as $field) { - if ($field->getAttribute('value') == $value) { - // Input element with correct value. - $found = TRUE; + if ($field->getAttribute('type') == 'checkbox') { + // Checkbox with the correct checked state if the value was passed + // as a boolean. + $found = !is_bool($value) || $field->isChecked() === $value; } - elseif ($field->find('xpath', '//option[@value = ' . (new Escaper())->escapeLiteral($value) . ' and @selected = "selected"]')) { + elseif ($field->getTagName() == 'select' && $field->find('xpath', '//option[@value = ' . (new Escaper())->escapeLiteral($value) . ' and @selected = "selected"]')) { // 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; } + elseif ($field->getAttribute('value') == $value) { + // Input element with correct value. + $found = TRUE; + } } } } @@ -773,6 +760,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..1110f33 100644 --- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php @@ -165,6 +165,64 @@ public function testLegacyFieldAsserts() { $this->assertFieldsByValue($this->xpath("//select[@id = 'edit-options']"), '2'); $this->assertFieldByXPath("//select[@id = 'edit-options']", '2'); + $this->assertNoField('invalid_name_and_id'); + $this->assertField('name'); + $this->assertField('edit-name'); + + // Test that the assertion fails correctly when searching by name. + try { + $this->assertNoField('name'); + $this->fail('The "name" field was not found based on name.'); + } + catch (ExpectationException $e) { + $this->pass('The "name" field was found by name.'); + } + + // Test that the assertion fails correctly when searching by id. + try { + $this->assertNoField('edit-name'); + $this->fail('The "name" field was not found based on id.'); + } + catch (ExpectationException $e) { + $this->pass('The "name" field was found by id.'); + } + + // Assert that assertion correctly fails when searching for the name field + // without a value. + try { + $this->assertFieldsByValue($this->xpath("//input[@id = 'edit-name']"), ''); + $this->fail('The "name" field, with no value was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The "name" field, with no value was found.'); + } + + $this->assertFieldByName('checkbox_enabled', TRUE); + $this->assertFieldByName('checkbox_disabled', FALSE); + + $this->assertNoFieldByName('checkbox_enabled', FALSE); + $this->assertNoFieldByName('checkbox_disabled', TRUE); + + try { + $this->assertFieldByName('checkbox_enabled', FALSE); + $this->fail('The checked "checkbox_enableRd" field was not found.'); + + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The checked "checkbox_enabled" field was found.'); + } + + try { + $this->assertNoFieldByName('checkbox_enabled', TRUE); + $this->fail('The checked "checkbox_enabled" field was not found.'); + } + catch (ExpectationException $e) { + $this->pass('The checked "checkbox_enabled" field was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The checked "checkbox_enabled" field was found.'); + } + $this->assertNoFieldByXPath('//notexisting'); $this->assertNoFieldByXPath("//input[@id = 'edit-name']", 'wrong value'); @@ -205,12 +263,12 @@ public function testLegacyFieldAsserts() { $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) { + catch (\PHPUnit_Framework_ExpectationFailedException $e) { $this->pass('The "name" field was not found.'); } @@ -237,6 +295,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'); @@ -253,7 +324,7 @@ public function testLegacyFieldAsserts() { $this->assertFieldById('Save', NULL); $this->fail('The field with id of "Save" was found.'); } - catch (ExpectationException $e) { + catch (\PHPUnit_Framework_ExpectationFailedException $e) { $this->pass($e->getMessage()); }