diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php index cc0c1df..7d686ae 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php @@ -2,7 +2,7 @@ namespace Drupal\FunctionalJavascriptTests\Core\Form; -use Behat\Mink\Element\DocumentElement; +use Behat\Mink\Element\TraversableElement; use Drupal\FunctionalJavascriptTests\JavascriptTestBase; /** @@ -26,22 +26,22 @@ public function testCheckboxTriggeredElements() { $trigger = $page->findField('checkbox_trigger'); - // Initial state: before the checkbox trigger is checked. + /* Initial state: before the checkbox trigger is checked. */ // Test that the textfield is visible. - $this->assertTrue($page->findField('textfield_invisible_when_checkbox_trigger_checked')->isVisible()); + $this->assertFieldVisible('textfield_invisible_when_checkbox_trigger_checked'); // Test that the details element is collapsed so the textfield inside is not // visible. - $this->assertFalse($page->findField('textfield_in_details')->isVisible()); + $this->assertFieldNotVisible('textfield_in_details'); // Change state: check the checkbox. $trigger->check(); // Test that the textfield is not visible anymore. - $this->assertFalse($page->findField('textfield_invisible_when_checkbox_trigger_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_invisible_when_checkbox_trigger_checked'); // Test that the details element is now open so the textfield inside is now // visible. - $this->assertTrue($page->findField('textfield_in_details')->isVisible()); + $this->assertFieldVisible('textfield_in_details'); // Change back to the initial state to avoid issues running the next tests. $trigger->uncheck(); @@ -55,19 +55,18 @@ public function testTextfieldTriggeredElements() { $page = $this->getSession()->getPage(); $trigger = $page->findField('textfield_trigger'); + $target = $page->findField('checkbox_unchecked_when_textfield_trigger_filled'); - // Initial state: before the textfield is filled. + /* Initial state: before the textfield is filled. */ // Test that the checkbox is checked. - $this->assertTrue($page->findField('checkbox_unchecked_when_textfield_trigger_filled') - ->isChecked()); + $this->assertTrue($target->isChecked()); // Change state: fill the textfield. $trigger->setValue('filled'); // Test that the checkbox is not checked anymore. - $this->assertFalse($page->findField('checkbox_unchecked_when_textfield_trigger_filled') - ->isChecked()); + $this->assertFalse($target->isChecked()); // Change back to the initial state to avoid issues running the next tests. $trigger->setValue(''); @@ -84,18 +83,18 @@ public function testRadiosTriggeredElements() { $trigger = $page->findField('radios_trigger'); - // Initial state: before the radios is checked. + /* Initial state: before the radios is checked. */ // Test that the fieldset element is not visible so the textfield inside is // not visible either. - $this->assertFalse($page->findField('textfield_in_fieldset')->isVisible()); + $this->assertFieldNotVisible('textfield_in_fieldset'); // Change state: check the 'Value 2' radio. $trigger->selectOption('value2'); // Test that the fieldset element is now visible so the textfield inside is // also visible. - $this->assertTrue($page->findField('textfield_in_fieldset')->isVisible()); + $this->assertFieldVisible('textfield_in_fieldset'); // Change back to the initial state to avoid issues running the next tests. $trigger->selectOption('value1'); @@ -112,44 +111,44 @@ public function testCheckboxesTriggeredElements() { $trigger2 = $page->findField('checkboxes_trigger[value2]'); $trigger3 = $page->findField('checkboxes_trigger[value3]'); - // Initial state: before any of the checkboxes is checked. + /* Initial state: before any of the checkboxes is checked. */ // Test that textfield dependant on checkbox 'value2' is not visible. - $this->assertFalse($page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_checkboxes_trigger_value2_checked'); // Test that textfield dependant on checkbox 'value3' is not visible. - $this->assertFalse($page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_checkboxes_trigger_value3_checked'); // Change state: check the 'Value 1' checkbox. $trigger1->check(); // Test that textfield dependant on checkbox 'value2' is still not visible. - $this->assertFalse($page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_checkboxes_trigger_value2_checked'); // Test that textfield dependant on checkbox 'value3' is still not visible. - $this->assertFalse($page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_checkboxes_trigger_value3_checked'); // Change state: check the 'Value 2' checkbox. $trigger2->check(); // Test that textfield dependant on checkbox 'value2' is now visible. - $this->assertTrue($page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_checkboxes_trigger_value2_checked'); // Test that textfield dependant on checkbox 'value3' is still not visible. - $this->assertFalse($page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_checkboxes_trigger_value3_checked'); // Change state: check the 'Value 3' checkbox. $trigger3->check(); // Test that textfield dependant on checkbox 'value2' is still visible. - $this->assertTrue($page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_checkboxes_trigger_value2_checked'); // Test that textfield dependant on checkbox 'value3' is now visible. - $this->assertTrue($page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_checkboxes_trigger_value3_checked'); // Change state: uncheck the 'Value 2' checkbox. $trigger2->uncheck(); // Test that textfield dependant on checkbox 'value2' is now invisible. - $this->assertFalse($page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_checkboxes_trigger_value2_checked'); // Test that textfield dependant on checkbox 'value3' is still visible. - $this->assertTrue($page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_checkboxes_trigger_value3_checked'); // Change back to the initial state to avoid issues running the next tests. $trigger1->uncheck(); @@ -166,40 +165,40 @@ public function testSelectTriggeredElements() { $trigger = $page->findField('select_trigger'); - // Initial state: before any option of the select box is selected. + /* Initial state: before any option of the select box is selected. */ // Test that item element dependant on select 'Value 2' option is not // visible. - $this->assertFalse($page->find('css', '#edit-item-visible-when-select-trigger-has-given-value')->isVisible()); + $this->assertSession()->assertElementNotVisible('css', '#edit-item-visible-when-select-trigger-has-given-value'); // Test that textfield dependant on select 'Value 3' option is not visible. - $this->assertFalse($page->findField('textfield_visible_when_select_trigger_has_given_value')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_select_trigger_has_given_value'); // Test that textfield dependant on select 'Value 2' or 'Value 3' options is // not visible. - $this->assertFalse($page->findField('textfield_visible_when_select_trigger_has_given_value_or_another')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_select_trigger_has_given_value_or_another'); // Change state: select the 'Value 2' option. $trigger->setValue('value2'); // Test that item element dependant on select 'Value 2' option is now // visible. - $this->assertTrue($page->find('css', '#edit-item-visible-when-select-trigger-has-given-value')->isVisible()); + $this->assertSession()->assertElementVisible('css', '#edit-item-visible-when-select-trigger-has-given-value'); // Test that textfield dependant on select 'Value 3' option is not visible. - $this->assertFalse($page->findField('textfield_visible_when_select_trigger_has_given_value')->isVisible()); + $this->assertFieldNotVisible('textfield_visible_when_select_trigger_has_given_value'); // Test that textfield dependant on select 'Value 2' or 'Value 3' options is // now visible. - $this->assertTrue($page->findField('textfield_visible_when_select_trigger_has_given_value_or_another')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_select_trigger_has_given_value_or_another'); // Change state: select the 'Value 3' option. $trigger->setValue('value3'); // Test that item element dependant on select 'Value 2' option is not // visible anymore. - $this->assertFalse($page->find('css', '#edit-item-visible-when-select-trigger-has-given-value')->isVisible()); + $this->assertSession()->assertElementNotVisible('css', '#edit-item-visible-when-select-trigger-has-given-value'); // Test that textfield dependant on select 'Value 3' option is now visible. - $this->assertTrue($page->findField('textfield_visible_when_select_trigger_has_given_value')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_select_trigger_has_given_value'); // Test that textfield dependant on select 'Value 2' or 'Value 3' options is // still visible. - $this->assertTrue($page->findField('textfield_visible_when_select_trigger_has_given_value_or_another')->isVisible()); + $this->assertFieldVisible('textfield_visible_when_select_trigger_has_given_value_or_another'); // Change back to the initial state to avoid issues running the next tests. $trigger->setValue('_none'); @@ -215,25 +214,25 @@ public function testMultipleTriggeredElements() { $selectTrigger = $page->findField('select_trigger'); $textfieldTrigger = $page->findField('textfield_trigger'); - // Initial state: before any option of the select box is selected. + /* Initial state: before any option of the select box is selected. */ // Test that item element dependant on select 'Value 2' option and textfield // is not visible. - $this->assertFalse($page->find('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled')->isVisible()); + $this->assertSession()->assertElementNotVisible('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled'); // Change state: select the 'Value 2' option. $selectTrigger->setValue('value2'); // Test that item element dependant on select 'Value 2' option and textfield // is still not visible. - $this->assertFalse($page->find('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled')->isVisible()); + $this->assertSession()->assertElementNotVisible('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled'); // Change state: fill the textfield. $textfieldTrigger->setValue('filled'); // Test that item element dependant on select 'Value 2' option and textfield // is now visible. - $this->assertTrue($page->find('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled')->isVisible()); + $this->assertSession()->assertElementVisible('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled'); // Change back to the initial state to avoid issues running the next tests. $selectTrigger->setValue('_none'); @@ -242,4 +241,31 @@ public function testMultipleTriggeredElements() { $textfieldTrigger->keyUp(8); } + /** + * Asserts that the given field is visible. + * + * @param string $locator + * One of id|name|label|value for the field. + * @param \Behat\Mink\Element\TraversableElement $container + * (optional) The document to check against. Defaults to the current page. + */ + public function assertFieldVisible($locator, TraversableElement $container = NULL) { + $this->assertSession()->assertElementVisible('named', ['field', $locator], $container); + } + + /** + * Asserts that the given field is not visible. + * + * @param string $locator + * One of id|name|label|value for the field. + * @param \Behat\Mink\Element\TraversableElement $container + * (optional) The document to check against. Defaults to the current page. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * When the element doesn't exist. + */ + public function assertFieldNotVisible($locator, TraversableElement $container = NULL) { + $this->assertSession()->assertElementNotVisible('named', ['field', $locator], $container); + } + } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php index 8d3ff47..5e8bbe9 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php @@ -2,6 +2,10 @@ namespace Drupal\FunctionalJavascriptTests; +use Behat\Mink\Element\Element; +use Behat\Mink\Element\ElementInterface; +use Behat\Mink\Exception\ElementHtmlException; +use Behat\Mink\Exception\ElementNotFoundException; use Drupal\Tests\WebAssert; /** @@ -28,4 +32,92 @@ public function assertWaitOnAjaxRequest($timeout = 10000, $message = 'Unable to } } + /** + * Asserts that the specific element is visible on the current page. + * + * @param string $selector_type + * The element selector type (css, xpath). + * @param string|array $selector + * The element selector. + * @param \Behat\Mink\Element\ElementInterface $container + * The document to check against. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * When the element doesn't exist. + */ + public function assertElementVisible($selector_type, $selector, ElementInterface $container = NULL) { + $container = $container ?: $this->session->getPage(); + $node = $container->find($selector_type, $selector); + if ($node === NULL) { + if (is_array($selector)) { + $selector = implode(' ', $selector); + } + throw new ElementNotFoundException($this->session->getDriver(), 'element', $selector_type, $selector); + } + $message = sprintf( + 'Element "%s" is not visible.', + $this->getMatchingElementRepresentation($selector_type, $selector) + ); + $this->assertElement($node->isVisible(), $message, $node); + } + + /** + * Asserts that the specific element is not visible on the current page. + * + * @param string $selector_type + * The element selector type (css, xpath). + * @param string|array $selector + * The element selector. + * @param \Behat\Mink\Element\ElementInterface $container + * The document to check against. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * When the element doesn't exist. + */ + public function assertElementNotVisible($selector_type, $selector, ElementInterface $container = NULL) { + $container = $container ?: $this->session->getPage(); + $node = $container->find($selector_type, $selector); + if ($node === NULL) { + if (is_array($selector)) { + $selector = implode(' ', $selector); + } + throw new ElementNotFoundException($this->session->getDriver(), 'element', $selector_type, $selector); + } + $message = sprintf( + 'Element "%s" is not visible.', + $this->getMatchingElementRepresentation($selector_type, $selector) + ); + $this->assertElement(!$node->isVisible(), $message, $node); + } + + /** + * {@inheritdoc} + */ + protected function assertElement($condition, $message, Element $element) { + if ($condition) { + return; + } + + throw new ElementHtmlException($message, $this->session->getDriver(), $element); + } + + /** + * {@inheritdoc} + */ + protected function getMatchingElementRepresentation($selector_type, $selector, $plural = FALSE) { + $pluralization = $plural ? 's' : ''; + + if (in_array($selector_type, ['named', 'named_exact', 'named_partial']) + && is_array($selector) && 2 === count($selector) + ) { + return sprintf('%s%s matching locator "%s"', $selector[0], $pluralization, $selector[1]); + } + + if (is_array($selector)) { + $selector = implode(' ', $selector); + } + + return sprintf('element%s matching %s "%s"', $pluralization, $selector_type, $selector); + } + }