diff --git a/composer.json b/composer.json index a5684a92068ac3a43a7945198b62eb1014233d64..9f70375403d2ffd7412fdc83ad3e476b031f8640 100644 --- a/composer.json +++ b/composer.json @@ -15,9 +15,9 @@ "drupal/core-vendor-hardening": "self.version" }, "require-dev": { - "behat/mink": "^1.10", - "behat/mink-browserkit-driver": "^2.1", - "behat/mink-selenium2-driver": "^1.4", + "behat/mink": "^1.11", + "behat/mink-browserkit-driver": "^2.2", + "behat/mink-selenium2-driver": "^1.7", "colinodell/psr-testlogger": "^1.2", "composer/composer": "^2.6.4", "drupal/coder": "^8.3.10", diff --git a/composer.lock b/composer.lock index 9454b2e82ca6c88001fa35873ee07db52ba41a5c..ce6897da59549a357ddeff5a9a98353fe1f4fc3b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8817574eb861631d2d3562adf1af8480", + "content-hash": "a4fad5d4f1355f96a953849799e211f4", "packages": [ { "name": "asm89/stack-cors", @@ -4444,26 +4444,28 @@ "packages-dev": [ { "name": "behat/mink", - "version": "v1.10.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/minkphp/Mink.git", - "reference": "19e58905632e7cfdc5b2bafb9b950a3521af32c5" + "reference": "d8527fdf8785aad38455fb426af457ab9937aece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/19e58905632e7cfdc5b2bafb9b950a3521af32c5", - "reference": "19e58905632e7cfdc5b2bafb9b950a3521af32c5", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/d8527fdf8785aad38455fb426af457ab9937aece", + "reference": "d8527fdf8785aad38455fb426af457ab9937aece", "shasum": "" }, "require": { "php": ">=7.2", - "symfony/css-selector": "^4.4 || ^5.0 || ^6.0" + "symfony/css-selector": "^4.4 || ^5.0 || ^6.0 || ^7.0" }, "require-dev": { + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", "phpunit/phpunit": "^8.5.22 || ^9.5.11", - "symfony/error-handler": "^4.4 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^5.4 || ^6.0" + "symfony/error-handler": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "behat/mink-browserkit-driver": "fast headless driver for any app without JS emulation", @@ -4502,37 +4504,40 @@ ], "support": { "issues": "https://github.com/minkphp/Mink/issues", - "source": "https://github.com/minkphp/Mink/tree/v1.10.0" + "source": "https://github.com/minkphp/Mink/tree/v1.11.0" }, - "time": "2022-03-28T14:22:43+00:00" + "time": "2023-12-09T11:23:23+00:00" }, { "name": "behat/mink-browserkit-driver", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", - "reference": "d2768e6c17b293d86d8fcff54cbb9e6ad938fee1" + "reference": "16d53476e42827ed3aafbfa4fde17a1743eafd50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/d2768e6c17b293d86d8fcff54cbb9e6ad938fee1", - "reference": "d2768e6c17b293d86d8fcff54cbb9e6ad938fee1", + "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/16d53476e42827ed3aafbfa4fde17a1743eafd50", + "reference": "16d53476e42827ed3aafbfa4fde17a1743eafd50", "shasum": "" }, "require": { - "behat/mink": "^1.9.0@dev", + "behat/mink": "^1.11.0@dev", + "ext-dom": "*", "php": ">=7.2", - "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", - "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0" + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0 || ^7.0" }, "require-dev": { "mink/driver-testsuite": "dev-master", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/error-handler": "^4.4 || ^5.0 || ^6.0", - "symfony/http-client": "^4.4 || ^5.0 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", - "symfony/mime": "^4.4 || ^5.0 || ^6.0", + "symfony/error-handler": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/http-client": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/mime": "^4.4 || ^5.0 || ^6.0 || ^7.0", "yoast/phpunit-polyfills": "^1.0" }, "type": "mink-driver", @@ -4567,34 +4572,36 @@ ], "support": { "issues": "https://github.com/minkphp/MinkBrowserKitDriver/issues", - "source": "https://github.com/minkphp/MinkBrowserKitDriver/tree/v2.1.0" + "source": "https://github.com/minkphp/MinkBrowserKitDriver/tree/v2.2.0" }, - "time": "2022-03-28T14:33:51+00:00" + "time": "2023-12-09T11:30:50+00:00" }, { "name": "behat/mink-selenium2-driver", - "version": "v1.6.0", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/minkphp/MinkSelenium2Driver.git", - "reference": "e5f8421654930da725499fb92983e6948c6f973e" + "reference": "4ca4083f305de7dff4434ac402dc4e3f39c0866a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/e5f8421654930da725499fb92983e6948c6f973e", - "reference": "e5f8421654930da725499fb92983e6948c6f973e", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/4ca4083f305de7dff4434ac402dc4e3f39c0866a", + "reference": "4ca4083f305de7dff4434ac402dc4e3f39c0866a", "shasum": "" }, "require": { - "behat/mink": "^1.9@dev", + "behat/mink": "^1.11@dev", "ext-json": "*", - "instaclick/php-webdriver": "^1.4", + "instaclick/php-webdriver": "^1.4.14", "php": ">=7.2" }, "require-dev": { "mink/driver-testsuite": "dev-master", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", "phpunit/phpunit": "^8.5.22 || ^9.5.11", - "symfony/error-handler": "^4.4 || ^5.0" + "symfony/error-handler": "^4.4 || ^5.0 || ^6.0 || ^7.0" }, "type": "mink-driver", "extra": { @@ -4635,9 +4642,9 @@ ], "support": { "issues": "https://github.com/minkphp/MinkSelenium2Driver/issues", - "source": "https://github.com/minkphp/MinkSelenium2Driver/tree/v1.6.0" + "source": "https://github.com/minkphp/MinkSelenium2Driver/tree/v1.7.0" }, - "time": "2022-03-28T14:55:17+00:00" + "time": "2023-12-09T11:58:45+00:00" }, { "name": "colinodell/psr-testlogger", diff --git a/composer/Metapackage/DevDependencies/composer.json b/composer/Metapackage/DevDependencies/composer.json index ea09439a0a1ba7845719bfa1a4d8ef8c4673e2a3..2d73ffd3baac45beb835dc4b2d9677fd2d64d806 100644 --- a/composer/Metapackage/DevDependencies/composer.json +++ b/composer/Metapackage/DevDependencies/composer.json @@ -7,9 +7,9 @@ "webflo/drupal-core-require-dev": "*" }, "require": { - "behat/mink": "^1.10", - "behat/mink-browserkit-driver": "^2.1", - "behat/mink-selenium2-driver": "^1.4", + "behat/mink": "^1.11", + "behat/mink-browserkit-driver": "^2.2", + "behat/mink-selenium2-driver": "^1.7", "colinodell/psr-testlogger": "^1.2", "composer/composer": "^2.6.4", "drupal/coder": "^8.3.10", diff --git a/composer/Metapackage/PinnedDevDependencies/composer.json b/composer/Metapackage/PinnedDevDependencies/composer.json index f168e3e13277f5c4e34c5880b8743a03b19abe2e..e163b8fe726050cdf6d79d0aebf643704a542c4a 100644 --- a/composer/Metapackage/PinnedDevDependencies/composer.json +++ b/composer/Metapackage/PinnedDevDependencies/composer.json @@ -8,9 +8,9 @@ }, "require": { "drupal/core": "11.x-dev", - "behat/mink": "v1.10.0", - "behat/mink-browserkit-driver": "v2.1.0", - "behat/mink-selenium2-driver": "v1.6.0", + "behat/mink": "v1.11.0", + "behat/mink-browserkit-driver": "v2.2.0", + "behat/mink-selenium2-driver": "v1.7.0", "colinodell/psr-testlogger": "v1.3.0", "composer/ca-bundle": "1.3.7", "composer/class-map-generator": "1.1.0", diff --git a/core/modules/block/tests/src/FunctionalJavascript/BlockDragTest.php b/core/modules/block/tests/src/FunctionalJavascript/BlockDragTest.php index 85a273f11866d4edde6bf0c861cef46334cb91a9..17b07dfe993880a1d20ceece7a3698ca1dacb6fe 100644 --- a/core/modules/block/tests/src/FunctionalJavascript/BlockDragTest.php +++ b/core/modules/block/tests/src/FunctionalJavascript/BlockDragTest.php @@ -38,6 +38,8 @@ protected function setUp(): void { * Tests drag and drop blocks. */ public function testDragAndDropBlocks() { + // Resize window to work around https://github.com/bitovi/syn/issues/164. + $this->getSession()->resizeWindow(1024, 2048); $this->drupalGet('admin/structure/block'); $assertSession = $this->assertSession(); $session = $this->getSession(); diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaEmbedFilterTestBase.php b/core/modules/media/tests/src/FunctionalJavascript/MediaEmbedFilterTestBase.php index 8bdf77fdce4a2f12ae441f044c016a848f349e0f..8c9c598ea411315f2d40ea81458efc8647e4a929 100644 --- a/core/modules/media/tests/src/FunctionalJavascript/MediaEmbedFilterTestBase.php +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaEmbedFilterTestBase.php @@ -115,7 +115,7 @@ public function providerTestValidations() { 'filters[filter_align][status]' => TRUE, 'filters[filter_caption][status]' => TRUE, 'filters[filter_html_image_secure][status]' => TRUE, - 'media_embed' => -5, + 'media_embed' => '-5', 'allowed_html' => "<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type='1 A I'> <li> <dl> <dt> <dd> <h2 id='jump-*'> <h3 id> <h4 id> <h5 id> <h6 id> <drupal-media data-entity-type data-entity-uuid data-view-mode>", 'expected_error_message' => 'The Embed media filter needs to be placed after the following filters: Align images, Caption images, Restrict images to this site.', ], @@ -124,7 +124,7 @@ public function providerTestValidations() { 'filters[filter_align][status]' => TRUE, 'filters[filter_caption][status]' => FALSE, 'filters[filter_html_image_secure][status]' => FALSE, - 'media_embed' => -5, + 'media_embed' => '-5', 'allowed_html' => '', 'expected_error_message' => 'The Embed media filter needs to be placed after the Align images filter.', ], @@ -133,7 +133,7 @@ public function providerTestValidations() { 'filters[filter_align][status]' => FALSE, 'filters[filter_caption][status]' => TRUE, 'filters[filter_html_image_secure][status]' => FALSE, - 'media_embed' => -5, + 'media_embed' => '-5', 'allowed_html' => '', 'expected_error_message' => 'The Embed media filter needs to be placed after the Caption images filter.', ], @@ -142,7 +142,7 @@ public function providerTestValidations() { 'filters[filter_align][status]' => FALSE, 'filters[filter_caption][status]' => FALSE, 'filters[filter_html_image_secure][status]' => TRUE, - 'media_embed' => -5, + 'media_embed' => '-5', 'allowed_html' => '', 'expected_error_message' => 'The Embed media filter needs to be placed after the Restrict images to this site filter.', ], @@ -151,7 +151,7 @@ public function providerTestValidations() { 'filters[filter_align][status]' => TRUE, 'filters[filter_caption][status]' => TRUE, 'filters[filter_html_image_secure][status]' => TRUE, - 'media_embed' => 5, + 'media_embed' => '5', 'allowed_html' => "<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type='1 A I'> <li> <dl> <dt> <dd> <h2 id='jump-*'> <h3 id> <h4 id> <h5 id> <h6 id> <drupal-media data-entity-type data-entity-uuid data-view-mode>", 'expected_error_message' => 'The Embed media filter needs to be placed after the Restrict images to this site filter.', ], diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php index 69d3628e3a6a31c641372148bdb82e33aa017a07..9af1d593440deb37bfbb72831b12cbb1a2714bde 100644 --- a/core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php +++ b/core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php @@ -192,10 +192,10 @@ public function testWidget() { $assert_session->buttonExists('field_twin_media_settings_edit')->press(); $this->assertElementExistsAfterWait('css', '#field-twin-media .tabledrag-toggle-weight')->press(); - $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_one][weight]')->selectOption(0); - $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_three][weight]')->selectOption(1); - $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_four][weight]')->selectOption(2); - $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_two][weight]')->selectOption(3); + $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_one][weight]')->selectOption('0'); + $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_three][weight]')->selectOption('1'); + $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_four][weight]')->selectOption('2'); + $assert_session->fieldExists('fields[field_twin_media][settings_edit_form][settings][media_types][type_two][weight]')->selectOption('3'); $assert_session->buttonExists('Save')->press(); $this->drupalGet('node/add/basic_page'); diff --git a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php index e0d9abaf7442039bf9e66bfe407c51be50c12d6d..6b1b5e360c26133d8920f41f5e7ef82d3e5dde69 100644 --- a/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php +++ b/core/modules/views/tests/src/FunctionalJavascript/PaginationAJAXTest.php @@ -82,7 +82,7 @@ public function testBasicPagination() { $this->assertEquals($expected_view_path, current($settings['views']['ajaxViews'])['view_path']); // Set the number of items displayed per page to 5 using the exposed pager. - $page->selectFieldOption('edit-items-per-page', 5); + $page->selectFieldOption('edit-items-per-page', '5'); $page->pressButton('Filter'); $session_assert->assertWaitOnAjaxRequest(); @@ -166,7 +166,7 @@ public function testDefaultFilterPagination() { $this->assertEquals($expected_view_path, current($settings['views']['ajaxViews'])['view_path']); // Set the number of items displayed per page to 5 using the exposed pager. - $page->selectFieldOption('edit-items-per-page', 5); + $page->selectFieldOption('edit-items-per-page', '5'); $page->pressButton('Filter'); $session_assert->assertWaitOnAjaxRequest(); diff --git a/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php b/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php index 964639173322992cfd78d9be25af5e7a1f954afa..ffdbc41533911397f74b9a92c6b50cf8db7480cd 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php @@ -6,6 +6,7 @@ use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Exception\DriverException; +use WebDriver\Element; use WebDriver\Exception; use WebDriver\Exception\UnknownError; use WebDriver\ServiceFactory; @@ -144,12 +145,13 @@ public function setValue($xpath, $value) { $not_clickable_exception = NULL; $result = $this->waitFor(10, function () use (&$not_clickable_exception, $xpath, $value) { try { + $element = $this->getWebDriverSession()->element('xpath', $xpath); // \Behat\Mink\Driver\Selenium2Driver::setValue() will call .blur() on // the element, modify that to trigger the "input" and "change" events // instead. They indicate the value has changed, rather than implying // user focus changes. This script only runs when Drupal javascript has // been loaded. - $this->executeJsOnXpath($xpath, <<<JS + $this->executeJsOnElement($element, <<<JS if (typeof Drupal !== 'undefined') { var node = {{ELEMENT}}; var original = node.blur; @@ -165,6 +167,12 @@ public function setValue($xpath, $value) { }; } JS); + if (!is_string($value) && strtolower($element->name()) === 'input' && in_array(strtolower($element->attribute('type')), ['text', 'number', 'radio'], TRUE)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $value = (string) $value; + } + parent::setValue($xpath, $value); return TRUE; } @@ -231,4 +239,26 @@ public function dragTo($sourceXpath, $destinationXpath) { } } + /** + * Executes JS on a given element. + * + * @param \WebDriver\Element $element + * The webdriver element. + * @param string $script + * The script to execute. + * + * @return mixed + * The result of executing the script. + */ + private function executeJsOnElement(Element $element, string $script) { + $script = str_replace('{{ELEMENT}}', 'arguments[0]', $script); + + $options = [ + 'script' => $script, + 'args' => [$element], + ]; + + return $this->getWebDriverSession()->execute($options); + } + } diff --git a/core/tests/Drupal/Tests/UiHelperTrait.php b/core/tests/Drupal/Tests/UiHelperTrait.php index 449cf2a78ecbbf39334df77102fc03a4ed27ab50..bcf5af79192b2d79fb6e7afb6dc547d53f1d29cb 100644 --- a/core/tests/Drupal/Tests/UiHelperTrait.php +++ b/core/tests/Drupal/Tests/UiHelperTrait.php @@ -84,14 +84,16 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) { foreach ($edit as $name => $value) { $field = $assert_session->fieldExists($name, $form); - // Provide support for the values '1' and '0' for checkboxes instead of - // TRUE and FALSE. - // @todo Get rid of supporting 1/0 by converting all tests cases using - // this to boolean values. - $field_type = $field->getAttribute('type'); - if ($field_type === 'checkbox') { - $value = (bool) $value; - } + $value = match ($field->getAttribute('type')) { + // Provide support for the values '1' and '0' for checkboxes instead of + // TRUE and FALSE. + // @todo Get rid of supporting 1/0 by converting all tests cases using + // this to boolean values. + 'checkbox' => (bool) $value, + // Mink only allows strings for text, number and radio button values. + 'text', 'number', 'radio' => (string) $value, + default => $value, + }; $field->setValue($value); } @@ -232,6 +234,16 @@ protected function drupalGet($path, array $options = [], array $headers = []) { $this->prepareRequest(); foreach ($headers as $header_name => $header_value) { + if (is_int($header_name)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + [$header_name, $header_value] = explode(':', $header_value); + } + if (is_null($header_value)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $header_value = ''; + } $session->setRequestHeader($header_name, $header_value); } diff --git a/core/tests/Drupal/Tests/WebAssert.php b/core/tests/Drupal/Tests/WebAssert.php index 9c36f9339e7ea857f39c7fb5f87f0087159e140c..68851e55b14f19e380ed77500ff6edca8794bc42 100644 --- a/core/tests/Drupal/Tests/WebAssert.php +++ b/core/tests/Drupal/Tests/WebAssert.php @@ -139,6 +139,11 @@ public function pageTextMatchesCount(int $count, string $regex, string $message * When the element doesn't exist. */ public function buttonExists($button, TraversableElement $container = NULL) { + if (!is_string($button)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $button = (string) $button; + } $container = $container ?: $this->session->getPage(); $node = $container->findButton($button); @@ -918,4 +923,49 @@ protected function buildStatusMessageSelector(string $message = NULL, string $ty return $selector; } + /** + * {@inheritdoc} + */ + public function responseHeaderEquals($name, $value) { + if (!is_string($name)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $name = (string) $name; + } + if ($value === NULL) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $this->responseHeaderDoesNotExist($name); + return; + } + if (!is_string($value)) { + $value = (string) $value; + } + parent::responseHeaderEquals($name, $value); + } + + /** + * {@inheritdoc} + */ + public function pageTextContains($text) { + if (!is_string($text)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $text = (string) $text; + } + parent::pageTextContains($text); + } + + /** + * {@inheritdoc} + */ + public function fieldValueEquals(string $field, $value, TraversableElement $container = NULL) { + if (!is_string($value)) { + // @todo Trigger deprecation in + // https://www.drupal.org/project/drupal/issues/3421105. + $value = (string) $value; + } + parent::fieldValueEquals($field, $value, $container); + } + }