From fc021f968a4503c4db4f306b94b2041cdcd164c3 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 16 Jun 2020 10:28:02 +0800 Subject: [PATCH 01/26] MDL-66979 behat: Switch to new W3C Behat driver This commit updates the composer dependencies to make use of the updated version of moodlehq/moodle-behat-extension which depends upon the php-webdriver/webdriver and relevant Mink WebDriver. --- composer.json | 15 +- composer.lock | 1344 ++++++++++++++++++++++++++++--------------------- 2 files changed, 764 insertions(+), 595 deletions(-) diff --git a/composer.json b/composer.json index 4e345aa7e84..152a1768437 100644 --- a/composer.json +++ b/composer.json @@ -4,16 +4,11 @@ "description": "Moodle - the world's open source learning platform", "type": "project", "homepage": "https://moodle.org", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/moodlehq/php-webdriver.git" - } - ], "require-dev": { "phpunit/phpunit": "8.5.*", - "moodlehq/behat-extension": "3.310.0", - "mikey179/vfsstream": "^1.6", - "instaclick/php-webdriver": "dev-local as 1.x-dev" - } + "moodlehq/behat-extension": "3.310.2", + "mikey179/vfsstream": "^1.6" + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/composer.lock b/composer.lock index 6ee34b7cc17..ea82ac7f46a 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": "104dc538011bde60b0cd2e7980b750b6", + "content-hash": "ecceb2ef6e976a6d579155fd11cd1b1e", "packages": [], "packages-dev": [ { @@ -85,6 +85,10 @@ "symfony", "testing" ], + "support": { + "issues": "https://github.com/Behat/Behat/issues", + "source": "https://github.com/Behat/Behat/tree/v3.6.1" + }, "time": "2020-02-06T09:54:48+00:00" }, { @@ -144,6 +148,10 @@ "gherkin", "parser" ], + "support": { + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/master" + }, "time": "2020-03-17T14:03:26+00:00" }, { @@ -205,6 +213,10 @@ "testing", "web" ], + "support": { + "issues": "https://github.com/minkphp/Mink/issues", + "source": "https://github.com/minkphp/Mink/tree/v1.8.1" + }, "time": "2020-03-11T15:45:53+00:00" }, { @@ -262,6 +274,10 @@ "browser", "testing" ], + "support": { + "issues": "https://github.com/minkphp/MinkBrowserKitDriver/issues", + "source": "https://github.com/minkphp/MinkBrowserKitDriver/tree/v1.3.4" + }, "time": "2020-03-11T09:49:45+00:00" }, { @@ -321,6 +337,10 @@ "test", "web" ], + "support": { + "issues": "https://github.com/Behat/MinkExtension/issues", + "source": "https://github.com/Behat/MinkExtension/tree/master" + }, "time": "2018-02-06T15:36:30+00:00" }, { @@ -376,69 +396,12 @@ "headless", "testing" ], + "support": { + "issues": "https://github.com/minkphp/MinkGoutteDriver/issues", + "source": "https://github.com/minkphp/MinkGoutteDriver/tree/master" + }, "time": "2016-03-05T09:04:22+00:00" }, - { - "name": "behat/mink-selenium2-driver", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/minkphp/MinkSelenium2Driver.git", - "reference": "312a967dd527f28980cce40850339cd5316da092" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/312a967dd527f28980cce40850339cd5316da092", - "reference": "312a967dd527f28980cce40850339cd5316da092", - "shasum": "" - }, - "require": { - "behat/mink": "~1.7@dev", - "instaclick/php-webdriver": "~1.1", - "php": ">=5.4" - }, - "require-dev": { - "mink/driver-testsuite": "dev-master" - }, - "type": "mink-driver", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Mink\\Driver\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Pete Otaqui", - "email": "pete@otaqui.com", - "homepage": "https://github.com/pete-otaqui" - }, - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Selenium2 (WebDriver) driver for Mink framework", - "homepage": "http://mink.behat.org/", - "keywords": [ - "ajax", - "browser", - "javascript", - "selenium", - "testing", - "webdriver" - ], - "time": "2020-03-11T14:43:21+00:00" - }, { "name": "behat/transliterator", "version": "v1.3.0", @@ -482,6 +445,10 @@ "slug", "transliterator" ], + "support": { + "issues": "https://github.com/Behat/Transliterator/issues", + "source": "https://github.com/Behat/Transliterator/tree/v1.3.0" + }, "time": "2020-01-14T16:39:13+00:00" }, { @@ -513,41 +480,40 @@ ], "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "homepage": "https://github.com/container-interop/container-interop", + "support": { + "issues": "https://github.com/container-interop/container-interop/issues", + "source": "https://github.com/container-interop/container-interop/tree/master" + }, "abandoned": "psr/container", "time": "2017-02-14T19:40:03+00:00" }, { "name": "doctrine/instantiator", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -561,7 +527,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -570,6 +536,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -584,25 +554,25 @@ "type": "tidelift" } ], - "time": "2020-05-29T17:27:14+00:00" + "time": "2020-11-10T18:47:58+00:00" }, { "name": "fabpot/goutte", - "version": "v3.3.0", + "version": "v3.3.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/Goutte.git", - "reference": "4ab5199e3ec0ffde0ee0b5ecf568a4fb8398dbae" + "reference": "80a23b64f44d54dd571d114c473d9d7e9ed84ca5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/4ab5199e3ec0ffde0ee0b5ecf568a4fb8398dbae", - "reference": "4ab5199e3ec0ffde0ee0b5ecf568a4fb8398dbae", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/80a23b64f44d54dd571d114c473d9d7e9ed84ca5", + "reference": "80a23b64f44d54dd571d114c473d9d7e9ed84ca5", "shasum": "" }, "require": { "guzzlehttp/guzzle": "^6.0", - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/browser-kit": "^4.4|^5.0", "symfony/css-selector": "^4.4|^5.0", "symfony/dom-crawler": "^4.4|^5.0" @@ -639,7 +609,11 @@ "keywords": [ "scraper" ], - "time": "2019-12-06T13:11:18+00:00" + "support": { + "issues": "https://github.com/FriendsOfPHP/Goutte/issues", + "source": "https://github.com/FriendsOfPHP/Goutte/tree/v3.3.1" + }, + "time": "2020-11-01T09:30:18+00:00" }, { "name": "guzzlehttp/guzzle", @@ -706,6 +680,10 @@ "rest", "web service" ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5" + }, "time": "2020-06-16T21:01:06+00:00" }, { @@ -757,6 +735,10 @@ "keywords": [ "promise" ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.0" + }, "time": "2020-09-30T07:37:28+00:00" }, { @@ -828,68 +810,11 @@ "uri", "url" ], - "time": "2020-09-30T07:37:11+00:00" - }, - { - "name": "instaclick/php-webdriver", - "version": "dev-local", - "source": { - "type": "git", - "url": "https://github.com/moodlehq/php-webdriver.git", - "reference": "3df827208ec104a9716aa8c30741e330da620c1e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/moodlehq/php-webdriver/zipball/3df827208ec104a9716aa8c30741e330da620c1e", - "reference": "3df827208ec104a9716aa8c30741e330da620c1e", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "^4.8", - "satooshi/php-coveralls": "^1.0||^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "WebDriver": "lib/" - } - }, - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Justin Bishop", - "email": "jubishop@gmail.com", - "role": "Developer" - }, - { - "name": "Anthon Pang", - "email": "apang@softwaredevelopment.ca", - "role": "Fork Maintainer" - } - ], - "description": "PHP WebDriver for Selenium 2", - "homepage": "http://instaclick.com/", - "keywords": [ - "browser", - "selenium", - "webdriver", - "webtest" - ], "support": { - "source": "https://github.com/moodlehq/php-webdriver/tree/local" + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" }, - "time": "2019-08-14T02:10:24+00:00" + "time": "2020-09-30T07:37:11+00:00" }, { "name": "mikey179/vfsstream", @@ -935,20 +860,25 @@ ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", + "support": { + "issues": "https://github.com/bovigo/vfsStream/issues", + "source": "https://github.com/bovigo/vfsStream/tree/master", + "wiki": "https://github.com/bovigo/vfsStream/wiki" + }, "time": "2019-10-30T15:31:00+00:00" }, { "name": "moodlehq/behat-extension", - "version": "v3.310.0", + "version": "v3.310.2", "source": { "type": "git", "url": "https://github.com/moodlehq/moodle-behat-extension.git", - "reference": "d05ea443ff24f90edb9b31c92e4dfe67c58a0b4b" + "reference": "a62d7b3ee349a4d0965535baa1f44f7585c644ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/moodlehq/moodle-behat-extension/zipball/d05ea443ff24f90edb9b31c92e4dfe67c58a0b4b", - "reference": "d05ea443ff24f90edb9b31c92e4dfe67c58a0b4b", + "url": "https://api.github.com/repos/moodlehq/moodle-behat-extension/zipball/a62d7b3ee349a4d0965535baa1f44f7585c644ba", + "reference": "a62d7b3ee349a4d0965535baa1f44f7585c644ba", "shasum": "" }, "require": { @@ -956,7 +886,7 @@ "behat/mink": "~1.8", "behat/mink-extension": "~2.3", "behat/mink-goutte-driver": "~1.2", - "behat/mink-selenium2-driver": "~1.4", + "oleg-andreyev/mink-phpwebdriver": "^1.0", "php": ">=7.2.0", "symfony/process": "^4.0 || ^5.0" }, @@ -976,6 +906,12 @@ "email": "david.monllao@gmail.com", "homepage": "http://moodle.com", "role": "Developer" + }, + { + "name": "Andrew Nicols", + "email": "andrew@nicols.co.uk", + "homepage": "http://moodle.com", + "role": "Developer" } ], "description": "Moodle behat extension", @@ -984,20 +920,23 @@ "Behat", "moodle" ], - "time": "2020-04-20T09:32:44+00:00" + "support": { + "source": "https://github.com/moodlehq/moodle-behat-extension/tree/v3.310.2" + }, + "time": "2021-01-18T00:55:56+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -1032,83 +971,107 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2020-11-13T09:40:50+00:00" }, { - "name": "paragonie/random_compat", - "version": "v9.99.99", + "name": "oleg-andreyev/mink-phpwebdriver", + "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + "url": "https://github.com/oleg-andreyev/MinkPhpWebDriver.git", + "reference": "70c267e7734e6bf7ae9a199d21cf26cc354c515c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "url": "https://api.github.com/repos/oleg-andreyev/MinkPhpWebDriver/zipball/70c267e7734e6bf7ae9a199d21cf26cc354c515c", + "reference": "70c267e7734e6bf7ae9a199d21cf26cc354c515c", "shasum": "" }, "require": { - "php": "^7" + "behat/mink": "^1.8", + "php": ">=7.2", + "php-webdriver/webdriver": "^1.8" }, "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" + "behat/mink-extension": "^2.3", + "ext-json": "*", + "mink/driver-testsuite": "dev-integration-branch", + "roave/security-advisories": "dev-master", + "symfony/phpunit-bridge": "^5.2" }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "OAndreyev\\Mink\\Driver\\": "src/" + } }, - "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" + "name": "Oleg Andreyev", + "email": "oleg@andreyev.lv", + "role": "Main Developer" } ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "description": "MinkPhpWebDriver driver for Mink framework", "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" + "W3C", + "ajax", + "browser", + "javascript", + "jsonwire", + "testing", + "webdriver" ], - "time": "2018-07-02T15:55:56+00:00" + "support": { + "issues": "https://github.com/oleg-andreyev/MinkPhpWebDriver/issues", + "source": "https://github.com/oleg-andreyev/MinkPhpWebDriver/tree/v1.0.0" + }, + "time": "2021-01-16T20:34:52+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1138,24 +1101,28 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, + "time": "2020-06-27T14:33:11+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "e4782611070e50613683d2b9a57730e9a3ba5451" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451", + "reference": "e4782611070e50613683d2b9a57730e9a3ba5451", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1185,7 +1152,82 @@ } ], "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.0.4" + }, + "time": "2020-12-13T23:18:30+00:00" + }, + { + "name": "php-webdriver/webdriver", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver.git", + "reference": "e3633154554605274cc9d59837f55a7427d72003" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/e3633154554605274cc9d59837f55a7427d72003", + "reference": "e3633154554605274cc9d59837f55a7427d72003", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-zip": "*", + "php": "^5.6 || ~7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.12", + "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0" + }, + "replace": { + "facebook/webdriver": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "ondram/ci-detector": "^2.1 || ^3.5", + "php-coveralls/php-coveralls": "^2.4", + "php-mock/php-mock-phpunit": "^1.1 || ^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0" + }, + "suggest": { + "ext-SimpleXML": "For Firefox profile creation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + }, + "files": [ + "lib/Exception/TimeoutException.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", + "homepage": "https://github.com/php-webdriver/php-webdriver", + "keywords": [ + "Chromedriver", + "geckodriver", + "php", + "selenium", + "webdriver" + ], + "support": { + "issues": "https://github.com/php-webdriver/php-webdriver/issues", + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.9.0" + }, + "time": "2020-11-19T15:21:05+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1234,6 +1276,10 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { @@ -1286,6 +1332,10 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, "time": "2020-09-03T19:13:55+00:00" }, { @@ -1331,20 +1381,24 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + }, "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", - "version": "1.12.1", + "version": "1.12.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + "reference": "245710e971a030f42e08f4912863805570f23d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", - "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", + "reference": "245710e971a030f42e08f4912863805570f23d39", "shasum": "" }, "require": { @@ -1356,7 +1410,7 @@ }, "require-dev": { "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { @@ -1394,29 +1448,33 @@ "spy", "stub" ], - "time": "2020-09-29T09:10:42+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + }, + "time": "2020-12-19T10:15:11+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "7.0.10", + "version": "7.0.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bb7c9a210c72e4709cdde67f8b7362f672f2225c", + "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.2", + "php": ">=7.2", "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.1.1", + "phpunit/php-token-stream": "^3.1.1 || ^4.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^4.2.2", "sebastian/version": "^2.0.1", @@ -1457,27 +1515,37 @@ "testing", "xunit" ], - "time": "2019-11-20T13:55:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.14" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-12-02T13:39:03+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1507,7 +1575,17 @@ "filesystem", "iterator" ], - "time": "2018-09-13T20:33:42+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:25:21+00:00" }, { "name": "phpunit/php-text-template", @@ -1548,27 +1626,31 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "2.1.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1597,25 +1679,35 @@ "keywords": [ "timer" ], - "time": "2019-06-07T04:22:29+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:20:02+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.1.1", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", + "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" @@ -1646,44 +1738,54 @@ "keywords": [ "tokenizer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "abandoned": true, - "time": "2019-09-17T06:23:10+00:00" + "time": "2020-11-30T08:38:46+00:00" }, { "name": "phpunit/phpunit", - "version": "8.5.8", + "version": "8.5.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" + "reference": "c25f79895d27b6ecd5abfa63de1606b786a461a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", - "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c25f79895d27b6ecd5abfa63de1606b786a461a3", + "reference": "c25f79895d27b6ecd5abfa63de1606b786a461a3", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2.0", + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.1", - "phar-io/manifest": "^1.0.3", - "phar-io/version": "^2.0.1", - "php": "^7.2", - "phpspec/prophecy": "^1.8.1", - "phpunit/php-code-coverage": "^7.0.7", + "myclabs/deep-copy": "^1.10.0", + "phar-io/manifest": "^2.0.1", + "phar-io/version": "^3.0.2", + "php": ">=7.2", + "phpspec/prophecy": "^1.10.3", + "phpunit/php-code-coverage": "^7.0.12", "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.1.2", "sebastian/comparator": "^3.0.2", "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.2", - "sebastian/exporter": "^3.1.1", + "sebastian/environment": "^4.2.3", + "sebastian/exporter": "^3.1.2", "sebastian/global-state": "^3.0.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0.1", @@ -1730,6 +1832,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.14" + }, "funding": [ { "url": "https://phpunit.de/donate.html", @@ -1740,7 +1846,7 @@ "type": "github" } ], - "time": "2020-06-22T07:06:58+00:00" + "time": "2021-01-17T07:37:30+00:00" }, { "name": "psr/container", @@ -1789,6 +1895,10 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, "time": "2017-02-14T16:28:37+00:00" }, { @@ -1835,6 +1945,10 @@ "psr", "psr-14" ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, "time": "2019-01-08T18:20:26+00:00" }, { @@ -1885,6 +1999,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -1925,27 +2042,31 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1970,29 +2091,39 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", "shasum": "" }, "require": { - "php": "^7.1", + "php": ">=7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -2010,6 +2141,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -2021,10 +2156,6 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -2034,24 +2165,34 @@ "compare", "equality" ], - "time": "2018-07-12T15:12:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:04:30+00:00" }, { "name": "sebastian/diff", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5 || ^8.0", @@ -2073,13 +2214,13 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", @@ -2090,24 +2231,34 @@ "unidiff", "unified diff" ], - "time": "2019-02-04T06:01:07+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:59:04+00:00" }, { "name": "sebastian/environment", - "version": "4.2.3", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5" @@ -2143,24 +2294,34 @@ "environment", "hhvm" ], - "time": "2019-11-20T08:46:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:53:42+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.2", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -2210,24 +2371,34 @@ "export", "exporter" ], - "time": "2019-09-14T09:02:43+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:47:53+00:00" }, { "name": "sebastian/global-state", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b", + "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b", "shasum": "" }, "require": { - "php": "^7.2", + "php": ">=7.2", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, @@ -2264,24 +2435,34 @@ "keywords": [ "global state" ], - "time": "2019-02-01T05:30:01+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:43:24+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, @@ -2311,24 +2492,34 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:40:27+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -2356,24 +2547,34 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:37:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -2394,14 +2595,14 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, { "name": "Adam Harvey", "email": "aharvey@php.net" @@ -2409,24 +2610,34 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:34:24+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "type": "library", "extra": { @@ -2451,24 +2662,34 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:30:19+00:00" }, { "name": "sebastian/type", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", "shasum": "" }, "require": { - "php": "^7.2" + "php": ">=7.2" }, "require-dev": { "phpunit/phpunit": "^8.2" @@ -2497,7 +2718,17 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", - "time": "2019-07-02T08:10:15+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:25:11+00:00" }, { "name": "sebastian/version", @@ -2540,20 +2771,24 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, "time": "2016-10-03T07:35:21+00:00" }, { "name": "symfony/browser-kit", - "version": "v4.4.15", + "version": "v4.4.18", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "9a1786e5020783605a30cff2ceed9aca030e8d80" + "reference": "85efcc33545ed472653eb2d00a4ab36e6258a5b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9a1786e5020783605a30cff2ceed9aca030e8d80", - "reference": "9a1786e5020783605a30cff2ceed9aca030e8d80", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/85efcc33545ed472653eb2d00a4ab36e6258a5b6", + "reference": "85efcc33545ed472653eb2d00a4ab36e6258a5b6", "shasum": "" }, "require": { @@ -2570,11 +2805,6 @@ "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\BrowserKit\\": "" @@ -2599,6 +2829,9 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/browser-kit/tree/v4.4.18" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2613,20 +2846,20 @@ "type": "tidelift" } ], - "time": "2020-10-02T08:38:15+00:00" + "time": "2020-12-18T07:41:31+00:00" }, { "name": "symfony/config", - "version": "v4.4.15", + "version": "v4.4.18", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7c5a1002178a612787c291a4f515f87b19176b61" + "reference": "e501c56d2fa70798075b9811d0eb4c27de491459" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7c5a1002178a612787c291a4f515f87b19176b61", - "reference": "7c5a1002178a612787c291a4f515f87b19176b61", + "url": "https://api.github.com/repos/symfony/config/zipball/e501c56d2fa70798075b9811d0eb4c27de491459", + "reference": "e501c56d2fa70798075b9811d0eb4c27de491459", "shasum": "" }, "require": { @@ -2648,11 +2881,6 @@ "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" @@ -2677,6 +2905,9 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v4.4.18" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2691,20 +2922,20 @@ "type": "tidelift" } ], - "time": "2020-10-02T07:34:48+00:00" + "time": "2020-12-09T08:58:17+00:00" }, { "name": "symfony/console", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8" + "reference": "47c02526c532fb381374dab26df05e7313978976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ae789a8a2ad189ce7e8216942cdb9b77319f5eb8", - "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8", + "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976", + "reference": "47c02526c532fb381374dab26df05e7313978976", "shasum": "" }, "require": { @@ -2741,11 +2972,6 @@ "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -2770,6 +2996,15 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2784,31 +3019,26 @@ "type": "tidelift" } ], - "time": "2020-10-07T15:23:00+00:00" + "time": "2020-12-18T08:03:05+00:00" }, { "name": "symfony/css-selector", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "e544e24472d4c97b2d11ade7caacd446727c6bf9" + "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/e544e24472d4c97b2d11ade7caacd446727c6bf9", - "reference": "e544e24472d4c97b2d11ade7caacd446727c6bf9", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/f789e7ead4c79e04ca9a6d6162fc629c89bd8054", + "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054", "shasum": "" }, "require": { "php": ">=7.2.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" @@ -2837,6 +3067,9 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2851,20 +3084,20 @@ "type": "tidelift" } ], - "time": "2020-05-20T17:43:50+00:00" + "time": "2020-12-08T17:02:38+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.4.15", + "version": "v4.4.18", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "89274c8847dff2ed703e481843eb9159ca25cc6e" + "reference": "3860f64c6deb2cb48b1ada27460c58ae479bdc0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/89274c8847dff2ed703e481843eb9159ca25cc6e", - "reference": "89274c8847dff2ed703e481843eb9159ca25cc6e", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3860f64c6deb2cb48b1ada27460c58ae479bdc0f", + "reference": "3860f64c6deb2cb48b1ada27460c58ae479bdc0f", "shasum": "" }, "require": { @@ -2895,11 +3128,6 @@ "symfony/yaml": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" @@ -2924,6 +3152,9 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v4.4.18" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2938,7 +3169,7 @@ "type": "tidelift" } ], - "time": "2020-09-10T10:08:39+00:00" + "time": "2020-12-18T07:41:31+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2988,6 +3219,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/master" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3006,16 +3240,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v4.4.15", + "version": "v4.4.18", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b" + "reference": "d44fbb02b458fe18d00fea18f24c97cefb87577e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bdcb7633a501770a0daefbf81d2e6b28c3864f2b", - "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/d44fbb02b458fe18d00fea18f24c97cefb87577e", + "reference": "d44fbb02b458fe18d00fea18f24c97cefb87577e", "shasum": "" }, "require": { @@ -3034,11 +3268,6 @@ "symfony/css-selector": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\DomCrawler\\": "" @@ -3063,6 +3292,9 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v4.4.18" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3077,20 +3309,20 @@ "type": "tidelift" } ], - "time": "2020-10-02T07:34:48+00:00" + "time": "2020-12-18T07:41:31+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f" + "reference": "1c93f7a1dff592c252574c79a8635a8a80856042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d5de97d6af175a9e8131c546db054ca32842dd0f", - "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1c93f7a1dff592c252574c79a8635a8a80856042", + "reference": "1c93f7a1dff592c252574c79a8635a8a80856042", "shasum": "" }, "require": { @@ -3121,11 +3353,6 @@ "symfony/http-kernel": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" @@ -3150,6 +3377,9 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3164,7 +3394,7 @@ "type": "tidelift" } ], - "time": "2020-09-18T14:27:32+00:00" + "time": "2020-12-18T08:03:05+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3226,6 +3456,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3244,16 +3477,16 @@ }, { "name": "symfony/filesystem", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "1a8697545a8d87b9f2f6b1d32414199cc5e20aae" + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/1a8697545a8d87b9f2f6b1d32414199cc5e20aae", - "reference": "1a8697545a8d87b9f2f6b1d32414199cc5e20aae", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d", "shasum": "" }, "require": { @@ -3261,11 +3494,6 @@ "symfony/polyfill-ctype": "~1.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -3290,6 +3518,9 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3304,24 +3535,24 @@ "type": "tidelift" } ], - "time": "2020-09-27T14:02:37+00:00" + "time": "2020-11-30T17:05:38+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" @@ -3329,7 +3560,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3366,6 +3597,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3380,24 +3614,24 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5" + "reference": "267a9adeb8ecb8071040a740930e077cdfb987af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b740103edbdcc39602239ee8860f0f45a8eb9aa5", - "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af", + "reference": "267a9adeb8ecb8071040a740930e077cdfb987af", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" @@ -3405,7 +3639,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3444,6 +3678,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3458,26 +3695,25 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251" + "reference": "0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/5dcab1bc7146cf8c1beaa4502a3d9be344334251", - "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44", + "reference": "0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=7.1", "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php70": "^1.10", "symfony/polyfill-php72": "^1.10" }, "suggest": { @@ -3486,7 +3722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3529,6 +3765,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3543,24 +3782,24 @@ "type": "tidelift" } ], - "time": "2020-08-04T06:02:08+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e" + "reference": "6e971c891537eb617a00bb07a43d182a6915faba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", - "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba", + "reference": "6e971c891537eb617a00bb07a43d182a6915faba", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" @@ -3568,7 +3807,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3610,6 +3849,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3624,24 +3866,24 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T17:09:11+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a" + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a", - "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" @@ -3649,7 +3891,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3687,6 +3929,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3701,106 +3946,29 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.18.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", - "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0|~9.99", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.18-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "639447d008615574653fb3bc60d1986d7172eaae" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/639447d008615574653fb3bc60d1986d7172eaae", - "reference": "639447d008615574653fb3bc60d1986d7172eaae", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3837,6 +4005,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3851,29 +4022,29 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca" + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fffa1a52a023e782cdcc221d781fe1ec8f87fcca", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3913,6 +4084,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3927,29 +4101,29 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981" + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/d87d5766cbf48d72388a9f6b85f280c8ad51f981", - "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "shasum": "" }, "require": { - "php": ">=7.0.8" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3993,6 +4167,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4007,20 +4184,20 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/process", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9" + "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d3a2e64866169586502f0cd9cab69135ad12cee9", - "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9", + "url": "https://api.github.com/repos/symfony/process/zipball/bd8815b8b6705298beaa384f04fabd459c10bedd", + "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd", "shasum": "" }, "require": { @@ -4028,11 +4205,6 @@ "symfony/polyfill-php80": "^1.15" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" @@ -4057,6 +4229,9 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4071,7 +4246,7 @@ "type": "tidelift" } ], - "time": "2020-09-02T16:23:27+00:00" + "time": "2020-12-08T17:03:37+00:00" }, { "name": "symfony/service-contracts", @@ -4133,6 +4308,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4151,16 +4329,16 @@ }, { "name": "symfony/string", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e" + "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4a9afe9d07bac506f75bcee8ed3ce76da5a9343e", - "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e", + "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", "shasum": "" }, "require": { @@ -4178,11 +4356,6 @@ "symfony/var-exporter": "^4.4|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\String\\": "" @@ -4218,6 +4391,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4232,20 +4408,20 @@ "type": "tidelift" } ], - "time": "2020-09-15T12:23:47+00:00" + "time": "2020-12-05T07:33:16+00:00" }, { "name": "symfony/translation", - "version": "v4.4.15", + "version": "v4.4.18", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "8494fa1bbf9d77fe1e7d50ac8ccfb80a858a98bd" + "reference": "c1001b7d75b3136648f94b245588209d881c6939" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/8494fa1bbf9d77fe1e7d50ac8ccfb80a858a98bd", - "reference": "8494fa1bbf9d77fe1e7d50ac8ccfb80a858a98bd", + "url": "https://api.github.com/repos/symfony/translation/zipball/c1001b7d75b3136648f94b245588209d881c6939", + "reference": "c1001b7d75b3136648f94b245588209d881c6939", "shasum": "" }, "require": { @@ -4279,11 +4455,6 @@ "symfony/yaml": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Translation\\": "" @@ -4308,6 +4479,9 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v4.4.18" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4322,7 +4496,7 @@ "type": "tidelift" } ], - "time": "2020-10-02T07:34:48+00:00" + "time": "2020-12-08T16:59:59+00:00" }, { "name": "symfony/translation-contracts", @@ -4383,6 +4557,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.3.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4401,16 +4578,16 @@ }, { "name": "symfony/yaml", - "version": "v5.1.7", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e147a68cb66a8b510f4b7481fe4da5b2ab65ec6a" + "reference": "290ea5e03b8cf9b42c783163123f54441fb06939" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e147a68cb66a8b510f4b7481fe4da5b2ab65ec6a", - "reference": "e147a68cb66a8b510f4b7481fe4da5b2ab65ec6a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/290ea5e03b8cf9b42c783163123f54441fb06939", + "reference": "290ea5e03b8cf9b42c783163123f54441fb06939", "shasum": "" }, "require": { @@ -4431,11 +4608,6 @@ "Resources/bin/yaml-lint" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" @@ -4460,6 +4632,9 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4474,7 +4649,7 @@ "type": "tidelift" } ], - "time": "2020-09-27T03:44:28+00:00" + "time": "2020-12-08T17:02:38+00:00" }, { "name": "theseer/tokenizer", @@ -4514,6 +4689,10 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/master" + }, "funding": [ { "url": "https://github.com/theseer", @@ -4569,24 +4748,19 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozart/assert/issues", + "source": "https://github.com/webmozart/assert/tree/master" + }, "time": "2020-07-08T17:02:28+00:00" } ], - "aliases": [ - { - "alias": "1.x-dev", - "alias_normalized": "1.9999999.9999999.9999999-dev", - "version": "dev-local", - "package": "instaclick/php-webdriver" - } - ], - "minimum-stability": "stable", - "stability-flags": { - "instaclick/php-webdriver": 20 - }, - "prefer-stable": false, + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } From c816ca79fab494f5945cdd6a416ecaf0ae85f368 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 12 Nov 2020 08:59:51 +0800 Subject: [PATCH 02/26] MDL-66979 behat: Core updates for W3C WebDriver This commit updates core Behat features to make use of the php-webdriver/webdriver library instead of the legacy Instaclick library. Most of these changes relate to use of features of WebDriver which we are required to use directly rather than through the Mink Driver. --- lib/behat/classes/behat_session_trait.php | 18 ++++++++---------- lib/behat/form_field/behat_form_field.php | 7 +++++-- lib/tests/behat/behat_general.php | 21 ++++++++++----------- lib/tests/behat/behat_hooks.php | 2 +- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/behat/classes/behat_session_trait.php b/lib/behat/classes/behat_session_trait.php index 5e9d3c0d35d..792c6872ae4 100644 --- a/lib/behat/classes/behat_session_trait.php +++ b/lib/behat/classes/behat_session_trait.php @@ -23,11 +23,12 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use Behat\Mink\Element\NodeElement; +use Behat\Mink\Element\Element; use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; use Behat\Mink\Exception\ElementNotFoundException; -use Behat\Mink\Element\NodeElement; -use Behat\Mink\Element\Element; +use Behat\Mink\Exception\NoSuchWindowException; use Behat\Mink\Session; // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. @@ -35,9 +36,8 @@ use Behat\Mink\Session; require_once(__DIR__ . '/component_named_replacement.php'); require_once(__DIR__ . '/component_named_selector.php'); -// Alias the WebDriver\Key class to behat_keys to make future transition to a different WebDriver implementation -// easier. -class_alias('WebDriver\\Key', 'behat_keys'); +// Alias the Facebook\WebDriver\WebDriverKeys class to behat_keys for better b/c with the older Instaclick driver. +class_alias('Facebook\WebDriver\WebDriverKeys', 'behat_keys'); /** * A trait containing functionality used by the behat base context, and form fields. @@ -253,9 +253,7 @@ trait behat_session_trait { * @param string[] $keys */ public static function type_keys(Session $session, array $keys): void { - $session->getDriver()->getWebDriverSession()->keys([ - 'value' => $keys, - ]); + $session->getDriver()->getWebDriver()->getKeyboard()->sendKeys($keys); } /** @@ -833,7 +831,7 @@ EOF; return M.util.pending_js.join(":"); })()')); $pending = self::evaluate_script_in_session($session, $jscode); - } catch (NoSuchWindow $nsw) { + } catch (NoSuchWindowException $nsw) { // We catch an exception here, in case we just closed the window we were interacting with. // No javascript is running if there is no window right? $pending = ''; @@ -973,7 +971,7 @@ EOF; } } - } catch (NoSuchWindow $e) { + } catch (NoSuchWindowException $e) { // If we were interacting with a popup window it will not exists after closing it. } catch (DriverException $e) { // Same reason as above. diff --git a/lib/behat/form_field/behat_form_field.php b/lib/behat/form_field/behat_form_field.php index c2aeee7559f..4da8002404a 100644 --- a/lib/behat/form_field/behat_form_field.php +++ b/lib/behat/form_field/behat_form_field.php @@ -218,12 +218,15 @@ class behat_form_field implements behat_session_interface { * @return int */ protected function get_internal_field_id() { - if (!$this->running_javascript()) { throw new coding_exception('You can only get an internal ID using the selenium driver.'); } - return $this->session->getDriver()->getWebDriverSession()->element('xpath', $this->field->getXPath())->getID(); + return $this->getSession() + ->getDriver() + ->getWebDriver() + ->findElement(WebDriverBy::xpath($node->getXpath())) + ->getID(); } /** diff --git a/lib/tests/behat/behat_general.php b/lib/tests/behat/behat_general.php index ec1e3a42984..70f9aa91532 100644 --- a/lib/tests/behat/behat_general.php +++ b/lib/tests/behat/behat_general.php @@ -271,7 +271,7 @@ class behat_general extends behat_base { * @Given /^I accept the currently displayed dialog$/ */ public function accept_currently_displayed_alert_dialog() { - $this->getSession()->getDriver()->getWebDriverSession()->accept_alert(); + $this->getSession()->getDriver()->getWebDriver()->switchTo()->alert()->accept(); } /** @@ -279,7 +279,7 @@ class behat_general extends behat_base { * @Given /^I dismiss the currently displayed dialog$/ */ public function dismiss_currently_displayed_alert_dialog() { - $this->getSession()->getDriver()->getWebDriverSession()->dismiss_alert(); + $this->getSession()->getDriver()->getWebDriver()->switchTo()->alert()->dismiss(); } /** @@ -418,7 +418,8 @@ class behat_general extends behat_base { */ public function i_click_on_confirming_the_dialogue($element, $selectortype) { $this->i_click_on($element, $selectortype); - $this->accept_currently_displayed_alert_dialog(); + $this->execute('behat_general::accept_currently_displayed_alert_dialog', []); + $this->wait_until_the_page_is_ready(); } /** @@ -431,7 +432,8 @@ class behat_general extends behat_base { */ public function i_click_on_dismissing_the_dialogue($element, $selectortype) { $this->i_click_on($element, $selectortype); - $this->dismiss_currently_displayed_alert_dialog(); + $this->execute('behat_general::dismiss_currently_displayed_alert_dialog', []); + $this->wait_until_the_page_is_ready(); } /** @@ -1802,16 +1804,16 @@ EOF; $modifier = trim($key); switch (strtoupper($key)) { case 'UP': - $keys[] = behat_keys::UP_ARROW; + $keys[] = behat_keys::ARROW_UP; break; case 'DOWN': - $keys[] = behat_keys::DOWN_ARROW; + $keys[] = behat_keys::ARROW_DOWN; break; case 'LEFT': - $keys[] = behat_keys::LEFT_ARROW; + $keys[] = behat_keys::ARROW_LEFT; break; case 'RIGHT': - $keys[] = behat_keys::RIGHT_ARROW; + $keys[] = behat_keys::ARROW_RIGHT; break; case 'HOME': $keys[] = behat_keys::HOME; @@ -1852,9 +1854,6 @@ EOF; throw new \coding_exception("Unknown key '$key'}"); } - // Always send the NULL key as the last key. - $keys[] = behat_keys::NULL_KEY; - behat_base::type_keys($this->getSession(), $keys); } diff --git a/lib/tests/behat/behat_hooks.php b/lib/tests/behat/behat_hooks.php index 17b8a0ed1a4..d7fc9e77287 100644 --- a/lib/tests/behat/behat_hooks.php +++ b/lib/tests/behat/behat_hooks.php @@ -644,7 +644,7 @@ EOF; // the following scenarios. Some browsers already closes the alert, so // wrapping in a try & catch. try { - $this->getSession()->getDriver()->getWebDriverSession()->accept_alert(); + $this->getSession()->getDriver()->getWebDriver()->switchTo()->alert()->accept(); } catch (Exception $e) { // Catching the generic one as we never know how drivers reacts here. } From 863d68a3443fb45fd427b880c65c367c73c40a98 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 15 Jun 2020 08:23:25 +0800 Subject: [PATCH 03/26] MDL-66979 behat: Rename selenium config to webdriver The PHP WebDriver Mink Driver does not necessarily require Selenium. It supports Selenium 3 upwards, and can be used directly with ChromeDriver, EdgeDriver, SafariDriver, GeckoDriver, and others. It therefore uses a slightly different configuraitno path. --- behat.yml.dist | 2 +- lib/behat/classes/behat_config_util.php | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/behat.yml.dist b/behat.yml.dist index 8c7e910002d..1da8a97436a 100644 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -7,7 +7,7 @@ default: Behat\MinkExtension: base_url: 'http://localhost:8000' goutte: null - selenium2: null + webdriver: null Moodle\BehatExtension: moodledirroot: /Should/Change/To/Moodle/www/dir steps_definitions: { } diff --git a/lib/behat/classes/behat_config_util.php b/lib/behat/classes/behat_config_util.php index 095c0e231ec..a7774410b0a 100644 --- a/lib/behat/classes/behat_config_util.php +++ b/lib/behat/classes/behat_config_util.php @@ -475,12 +475,12 @@ class behat_config_util { $parallelruns = $this->get_number_of_parallel_run(); } - $selenium2wdhost = array('wd_host' => 'http://localhost:4444/wd/hub'); + $webdriverwdhost = array('wd_host' => 'http://localhost:4444/wd/hub'); // If parallel run, then set wd_host if specified. if (!empty($currentrun) && !empty($parallelruns)) { - // Set proper selenium2 wd_host if defined. + // Set proper webdriver wd_host if defined. if (!empty($CFG->behat_parallel_run[$currentrun - 1]['wd_host'])) { - $selenium2wdhost = array('wd_host' => $CFG->behat_parallel_run[$currentrun - 1]['wd_host']); + $webdriverwdhost = array('wd_host' => $CFG->behat_parallel_run[$currentrun - 1]['wd_host']); } } @@ -525,7 +525,7 @@ class behat_config_util { 'Behat\MinkExtension' => array( 'base_url' => $CFG->behat_wwwroot, 'goutte' => null, - 'selenium2' => $selenium2wdhost + 'webdriver' => $webdriverwdhost ), 'Moodle\BehatExtension' => array( 'moodledirroot' => $CFG->dirroot, @@ -688,7 +688,7 @@ class behat_config_util { $behatprofileextension = array( 'extensions' => array( 'Behat\MinkExtension' => array( - 'selenium2' => $seleniumconfig, + 'webdriver' => $seleniumconfig, ) ) ); @@ -948,11 +948,11 @@ class behat_config_util { $oldconfigvalues = array(); if (isset($values['extensions']['Behat\MinkExtension\Extension'])) { $extensionvalues = $values['extensions']['Behat\MinkExtension\Extension']; - if (isset($extensionvalues['selenium2']['browser'])) { - $oldconfigvalues['browser'] = $extensionvalues['selenium2']['browser']; + if (isset($extensionvalues['webdriver']['browser'])) { + $oldconfigvalues['browser'] = $extensionvalues['webdriver']['browser']; } - if (isset($extensionvalues['selenium2']['wd_host'])) { - $oldconfigvalues['wd_host'] = $extensionvalues['selenium2']['wd_host']; + if (isset($extensionvalues['webdriver']['wd_host'])) { + $oldconfigvalues['wd_host'] = $extensionvalues['webdriver']['wd_host']; } if (isset($extensionvalues['capabilities'])) { $oldconfigvalues['capabilities'] = $extensionvalues['capabilities']; From ca2acd10c9c8f64252dde1441df62282320fcbaf Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 15 Jun 2020 10:20:55 +0800 Subject: [PATCH 04/26] MDL-66979 behat: Handle JS on elements better This change introduces a new function to execute Javascript directly on a node. This should not, ordinarily, be used directly by steps, but may be required in other parts of the Behat interaction. --- lib/behat/classes/behat_session_trait.php | 60 ++++++++++++++++++++--- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/lib/behat/classes/behat_session_trait.php b/lib/behat/classes/behat_session_trait.php index 792c6872ae4..2def65d9b65 100644 --- a/lib/behat/classes/behat_session_trait.php +++ b/lib/behat/classes/behat_session_trait.php @@ -30,6 +30,9 @@ use Behat\Mink\Exception\ExpectationException; use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Exception\NoSuchWindowException; use Behat\Mink\Session; +use Facebook\WebDriver\Exception\ScriptTimeoutException; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverElement; // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. @@ -1077,17 +1080,62 @@ EOF; if (!$this->running_javascript()) { $node->click(); } - $this->ensure_node_is_visible($node); // Ensures hidden elements can't be clicked. - $xpath = $node->getXpath(); $driver = $this->getSession()->getDriver(); - if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) { - $script = "Syn.click({{ELEMENT}})"; - $driver->triggerSynScript($xpath, $script); + if ($driver instanceof \Moodle\BehatExtension\Driver\WebDriver) { + $this->execute_js_on_node($node, '{{ELEMENT}}.click();'); } else { - $driver->click($xpath); + $this->ensure_node_is_visible($node); // Ensures hidden elements can't be clicked. + $driver->click($node->getXpath()); } } + /** + * Execute JS on the specified NodeElement. + * + * @param NodeElement $node + * @param string $script + * @param bool $async + */ + protected function execute_js_on_node(NodeElement $node, string $script, bool $async = false): void { + $driver = $this->getSession()->getDriver(); + if (!($driver instanceof \Moodle\BehatExtension\Driver\WebDriver)) { + throw new \coding_exception('Unknown driver'); + } + + if (preg_match('/^function[\s\(]/', $script)) { + $script = preg_replace('/;$/', '', $script); + $script = '(' . $script . ')'; + } + + $script = str_replace('{{ELEMENT}}', 'arguments[0]', $script); + + $webdriver = $driver->getWebDriver(); + + $element = $this->get_webdriver_element_from_node_element($node); + if ($async) { + try { + $webdriver->executeAsyncScript($script, [$element]); + } catch (ScriptTimeoutException $e) { + throw new DriverException($e->getMessage(), $e->getCode(), $e); + } + } else { + $webdriver->executeScript($script, [$element]); + } + } + + /** + * Translate a Mink NodeElement into a WebDriver Element. + * + * @param NodeElement $node + * @return WebDriverElement + */ + protected function get_webdriver_element_from_node_element(NodeElement $node): WebDriverElement { + return $this->getSession() + ->getDriver() + ->getWebDriver() + ->findElement(WebDriverBy::xpath($node->getXpath())); + } + /** * Convert page names to URLs for steps like 'When I am on the "[page name]" page'. * From e89be896df5bbb4227f43de51e0e44aaff261eb1 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 23 Jun 2020 10:39:45 +0800 Subject: [PATCH 05/26] MDL-66979 mod_data: Improve behat chart data step Charts data visibility is more reliable when checked via the aria-expanded attribute. The isVisible attribute can cause some failures under Firefox. --- mod/feedback/tests/behat/behat_mod_feedback.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mod/feedback/tests/behat/behat_mod_feedback.php b/mod/feedback/tests/behat/behat_mod_feedback.php index e95581de263..23bf53a12f1 100644 --- a/mod/feedback/tests/behat/behat_mod_feedback.php +++ b/mod/feedback/tests/behat/behat_mod_feedback.php @@ -165,9 +165,7 @@ class behat_mod_feedback extends behat_base { // If chart data is not visible then expand. $node = $this->get_selected_node("xpath_element", $charttabledataxpath); if ($node) { - if (!$node->isVisible()) { - // Focus on node, before checking if it's visible. - $node->focus(); + if ($node->getAttribute('aria-expanded') === 'false') { $this->execute('behat_general::i_click_on_in_the', array( get_string('showchartdata'), 'link', From 330b665f8202fb1bcf1e229b312dab09048b7630 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 23 Jun 2020 10:40:26 +0800 Subject: [PATCH 06/26] MDL-66979 behat: iFrames must have a name for switchTo The W3C WebDriver protocol supports switching of contexts using a named context, and not the class asscoiated with that context. --- lib/behat/classes/partial_named_selector.php | 2 +- lib/tests/behat/behat_general.php | 41 ++++++-------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/lib/behat/classes/partial_named_selector.php b/lib/behat/classes/partial_named_selector.php index 74054eeb4a8..3689733441e 100644 --- a/lib/behat/classes/partial_named_selector.php +++ b/lib/behat/classes/partial_named_selector.php @@ -235,7 +235,7 @@ XPATH .//descendant::input[@id = //label[contains(normalize-space(string(.)), %locator%)]/@for]/ancestor::*[@data-fieldtype = 'autocomplete'] XPATH , 'iframe' => <<(?:[^"]|\\")*)" iframe$/ - * @param string $iframename - */ - public function switch_to_iframe($iframename) { - - // We spin to give time to the iframe to be loaded. - // Using extended timeout as we don't know about which - // kind of iframe will be loaded. - $this->spin( - function($context, $iframename) { - $context->getSession()->switchToIFrame($iframename); - - // If no exception we are done. - return true; - }, - $iframename, - behat_base::get_extended_timeout() - ); - } - - /** - * Switches to the iframe containing specified class. - * * @Given /^I switch to "(?P(?:[^"]|\\")*)" class iframe$/ - * @param string $classname + * @param string $name The name of the iframe */ - public function switch_to_class_iframe($classname) { + public function switch_to_iframe($name) { // We spin to give time to the iframe to be loaded. // Using extended timeout as we don't know about which // kind of iframe will be loaded. $this->spin( - function($context, $classname) { - $iframe = $this->find('iframe', $classname); - if (!empty($iframe->getAttribute('id'))) { - $iframename = $iframe->getAttribute('id'); - } else { + function($context) use ($name){ + $iframe = $context->find('iframe', $name); + if ($iframe->hasAttribute('name')) { $iframename = $iframe->getAttribute('name'); + } else { + if (!$this->running_javascript()) { + throw new \coding_exception('iframe must have a name attribute to use the switchTo command.'); + } + $iframename = uniqid(); + $this->execute_js_on_node($iframe, "{{ELEMENT}}.name = '{$iframename}';"); } $context->getSession()->switchToIFrame($iframename); // If no exception we are done. return true; }, - $classname, behat_base::get_extended_timeout() ); } From d1e52f70862e7252cd202435ebd288bc767c21bf Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 26 Jun 2020 13:18:17 +0800 Subject: [PATCH 07/26] MDL-66979 behat: Update passwordunmask form field control Update the passwordunmask form field type for behat to interact with the form element as a human would rather than via synthetic event triggers. --- .../form_field/behat_form_passwordunmask.php | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/lib/behat/form_field/behat_form_passwordunmask.php b/lib/behat/form_field/behat_form_passwordunmask.php index cfc48c26c74..91840fdfdce 100644 --- a/lib/behat/form_field/behat_form_passwordunmask.php +++ b/lib/behat/form_field/behat_form_passwordunmask.php @@ -48,28 +48,21 @@ class behat_form_passwordunmask extends behat_form_text { * @return void */ public function set_value($value) { - if ($this->running_javascript()) { - $id = $this->field->getAttribute('id'); - $js = <<session, $js); + if (!$this->running_javascript()) { + $this->field->setValue($value); + + return; } - $this->field->setValue($value); + $id = $this->field->getAttribute('id'); + $wrapper = $this->field->getParent()->getParent()->find('css', '[data-passwordunmask="wrapper"]'); + $wrapper->click(); + $this->wait_for_pending_js(); - // Ensure all pending JS is finished. - if ($this->running_javascript()) { - // Press enter key after setting password, so we have a stable page. - $this->field->keyDown(13); - $this->field->keyPress(13); - $this->field->keyUp(13); - $this->session->wait(behat_base::get_timeout() * 1000, behat_base::PAGE_READY_JS); - } + behat_base::type_keys($this->session, str_split($value)); + $this->wait_for_pending_js(); + + // Press enter key after setting password to save. + behat_base::type_keys($this->session, [behat_keys::ENTER]); } } From 5212bfc961929c311df630de4ba8060351d06dd7 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 26 Jun 2020 13:18:38 +0800 Subject: [PATCH 08/26] MDL-66979 behat: Use tab to blur current focus The focus should be on something, rather than removed. The way in which focus removal works can lead to side effects. --- enrol/tests/behat/behat_enrol.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enrol/tests/behat/behat_enrol.php b/enrol/tests/behat/behat_enrol.php index bd48efcbb09..872a8aabf0f 100644 --- a/enrol/tests/behat/behat_enrol.php +++ b/enrol/tests/behat/behat_enrol.php @@ -66,7 +66,7 @@ class behat_enrol extends behat_base { // Ensure we get button in focus, before pressing button. if ($this->running_javascript()) { - $this->execute("behat_general::i_take_focus_off_field", array(get_string('addinstance', 'enrol'), "button")); + $this->execute('behat_general::i_press_named_key', ['', 'tab']); } // Save changes. From eec766f375e941b363d2b956cefc4c7e8aa91f36 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 25 Nov 2019 08:03:47 +0800 Subject: [PATCH 09/26] MDL-66979 behat: Fix window switching Normalise switching of window contexts by setting the main window name to a null. Where the window has no name (null/empty), then the root context is selected. --- lib/tests/behat/behat_forms.php | 4 +++- lib/tests/behat/behat_general.php | 14 ++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/tests/behat/behat_forms.php b/lib/tests/behat/behat_forms.php index 2b92271a686..ed2f2953a06 100644 --- a/lib/tests/behat/behat_forms.php +++ b/lib/tests/behat/behat_forms.php @@ -67,9 +67,11 @@ class behat_forms extends behat_base { // Ensures the button is present, before pressing. $buttonnode = $this->find_button($button); $buttonnode->press(); + $this->wait_for_pending_js(); + $this->look_for_exceptions(); // Switch to main window. - $this->getSession()->switchToWindow(behat_general::MAIN_WINDOW_NAME); + $this->execute('behat_general::switch_to_the_main_window'); } /** diff --git a/lib/tests/behat/behat_general.php b/lib/tests/behat/behat_general.php index a108c40e290..0f555d56b57 100644 --- a/lib/tests/behat/behat_general.php +++ b/lib/tests/behat/behat_general.php @@ -203,13 +203,11 @@ class behat_general extends behat_base { * @param string $windowname */ public function switch_to_window($windowname) { - // In Behat, some browsers (e.g. Chrome) are unable to switch to a - // window without a name, and by default the main browser window does - // not have a name. To work-around this, when we switch away from an - // unnamed window (presumably the main window) to some other named - // window, then we first set the main window name to a conventional - // value that we can later use this name to switch back. - $this->execute_script('if (window.name == "") window.name = "' . self::MAIN_WINDOW_NAME . '"'); + if ($windowname === self::MAIN_WINDOW_NAME) { + // When switching to the main window normalise the window name to null. + // This is normalised further in the Mink driver to the root window ID. + $windowname = null; + } $this->getSession()->switchToWindow($windowname); } @@ -220,7 +218,7 @@ class behat_general extends behat_base { * @Given /^I switch to the main window$/ */ public function switch_to_the_main_window() { - $this->getSession()->switchToWindow(self::MAIN_WINDOW_NAME); + $this->switch_to_window(self::MAIN_WINDOW_NAME); } /** From 035d4eb72a3cc8add0a48b62a2435431485e43ff Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 26 Jun 2020 21:18:24 +0800 Subject: [PATCH 10/26] MDL-66979 behat: Scroll nodes into view before hover The W3C Specification does not require that a NodeElement be in the current viewport before triggering a mouseOver. As a result the mouseOver will generate an Exception because the element is not in the viewport, and the X/Y co-ordinates are invalid. To handle this the node is scrolled into view. --- lib/tests/behat/behat_general.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tests/behat/behat_general.php b/lib/tests/behat/behat_general.php index 0f555d56b57..effa94ce047 100644 --- a/lib/tests/behat/behat_general.php +++ b/lib/tests/behat/behat_general.php @@ -346,9 +346,9 @@ class behat_general extends behat_base { * @param string $selectortype The type of what we look for */ public function i_hover($element, $selectortype) { - // Gets the node based on the requested selector type and locator. $node = $this->get_selected_node($selectortype, $element); + $this->execute_js_on_node($node, '{{ELEMENT}}.scrollIntoView();'); $node->mouseOver(); } From ac0f7dd2ab2fd2ad364404bdd7306f109372f9b7 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 26 Jun 2020 21:34:30 +0800 Subject: [PATCH 11/26] MDL-66979 scorm: Increase behat window size On Firefox there can be some issues with ensuring that all nodes are visible in order to click them. This is likely an upstream geckodriver bug and not one that can be easily addressed across all of Moodle. In this instance the "Next" button is just outside the Visible Window, but it is in an iFrame which is fully visible. In this situation Firefox is unable to click the button but does not error. --- mod/scorm/tests/behat/save_progress_on_unload.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/mod/scorm/tests/behat/save_progress_on_unload.feature b/mod/scorm/tests/behat/save_progress_on_unload.feature index 66c274aeb06..d6b6550953e 100644 --- a/mod/scorm/tests/behat/save_progress_on_unload.feature +++ b/mod/scorm/tests/behat/save_progress_on_unload.feature @@ -15,6 +15,7 @@ Feature: Confirm progress gets saved on unload events | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | + And I change window size to "large" @javascript Scenario: Test progress gets saved correctly when the user navigates away from the scorm activity From 084973f8a2c06c7f0b27fb0c7dceb47173c10283 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Sun, 28 Jun 2020 19:51:35 +0800 Subject: [PATCH 12/26] MDL-66979 behat: Remove unnecessary steps which fail These steps were completely pointless and were failing with the W3C Webdriver becuase focus was never on the Update Profile button in the first place. At a minimum we should remove the Focus change step as it not valid, but the following step is also pointless. --- admin/tool/behat/tests/behat/manipulate_forms.feature | 2 -- 1 file changed, 2 deletions(-) diff --git a/admin/tool/behat/tests/behat/manipulate_forms.feature b/admin/tool/behat/tests/behat/manipulate_forms.feature index 8e4f776fcdf..de3670d8a64 100644 --- a/admin/tool/behat/tests/behat/manipulate_forms.feature +++ b/admin/tool/behat/tests/behat/manipulate_forms.feature @@ -14,8 +14,6 @@ Feature: Forms manipulation Then the field "First name" matches value "Field value" And the "Select a country" select box should contain "Japan" And the field "New password" matches value "TestPass" - And I take focus off "Update profile" "button" - And I press "Update profile" @javascript Scenario: Expand all fieldsets and advanced elements From 2b0b259d09e843ba20feb4e2083dd8660698436b Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 12 Nov 2020 13:16:58 +0800 Subject: [PATCH 13/26] MDL-66979 group: Replace direct element interaction with steps The W3C WebDriver leads to faster operation of individual steps which highlights where WebDriver is moving to a new step faster than the browser can process it. The solution here is to use the `execute` function to interact with the browsers as this makes use of the various wait and check steps. --- group/tests/behat/behat_groups.php | 44 ++++++------------------------ 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/group/tests/behat/behat_groups.php b/group/tests/behat/behat_groups.php index 21a550989cf..86be91b6e9b 100644 --- a/group/tests/behat/behat_groups.php +++ b/group/tests/behat/behat_groups.php @@ -48,48 +48,20 @@ class behat_groups extends behat_base { * @param string $groupname */ public function i_add_user_to_group_members($userfullname, $groupname) { + // Select the group in the select. + $this->execute('behat_forms::i_set_the_field_to', [get_string('groups', 'core'), $this->escape($groupname)]); - $userfullname = behat_context_helper::escape($userfullname); + // Press "Add/remove users". + $this->execute('behat_general::i_click_on', [get_string('adduserstogroup', 'group'), "button"]); - // Using a xpath liternal to avoid problems with quotes and double quotes. - $groupname = behat_context_helper::escape($groupname); - - // We don't know the option text as it contains the number of users in the group. - $select = $this->find_field('groups'); - $xpath = "//select[@id='groups']/descendant::option[contains(., $groupname)]"; - $groupoption = $this->find('xpath', $xpath); - $fulloption = $groupoption->getText(); - $select->selectOption($fulloption); - - // This is needed by some drivers to ensure relevant event is triggred and button is enabled. - $driver = $this->getSession()->getDriver(); - if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) { - $script = "Syn.trigger('change', {}, {{ELEMENT}})"; - $driver->triggerSynScript($select->getXpath(), $script); - } - $this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS); - - // Here we don't need to wait for the AJAX response. - $this->find_button(get_string('adduserstogroup', 'group'))->click(); - - // Wait for add/remove members page to be loaded. - $this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS); - - // Getting the option and selecting it. - $select = $this->find_field('addselect'); - $xpath = "//select[@id='addselect']/descendant::option[contains(., $userfullname)]"; - $memberoption = $this->find('xpath', $xpath); - $fulloption = $memberoption->getText(); - $select->selectOption($fulloption); + // Select the user. + $this->execute('behat_forms::i_set_the_field_to', ["addselect", $this->escape($userfullname)]); // Click add button. - $this->find_button(get_string('add'))->click(); - - // Wait for the page to load. - $this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS); + $this->execute('behat_general::i_click_on', [get_string('add', 'core'), "button"]); // Returning to the main groups page. - $this->find_button(get_string('backtogroups', 'group'))->click(); + $this->execute('behat_general::i_click_on', [get_string('backtogroups', 'group'), "button"]); } /** From cbb2547c32333758b18a325c2015b86dca6618a5 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 12 Nov 2020 13:17:29 +0800 Subject: [PATCH 14/26] MDL-66979 behat: Remove manually triggered events Behat should not trigger Synthetic browser events. It is incorrect to do so as the UI should be used to trigger events correctly. The W3C WebDriver specification explicitly states when and where these events will be triggered from (the browser) and therefore there is no ambiguity and no need to synthetically trigger them from Behat. --- lib/behat/form_field/behat_form_checkbox.php | 19 ------------- lib/behat/form_field/behat_form_select.php | 29 -------------------- 2 files changed, 48 deletions(-) diff --git a/lib/behat/form_field/behat_form_checkbox.php b/lib/behat/form_field/behat_form_checkbox.php index 5cd624aca21..67ba66c30cc 100644 --- a/lib/behat/form_field/behat_form_checkbox.php +++ b/lib/behat/form_field/behat_form_checkbox.php @@ -57,9 +57,6 @@ class behat_form_checkbox extends behat_form_field { // Check it if it should be checked and it is not. $this->field->click(); - // Trigger the onchange event as triggered when 'checking' the checkbox. - $this->trigger_on_change(); - } else if (empty($value) && $this->field->isChecked()) { if (!$this->running_javascript()) { @@ -69,9 +66,6 @@ class behat_form_checkbox extends behat_form_field { // Uncheck if it is checked and shouldn't. $this->field->click(); - - // Trigger the onchange event as triggered when 'checking' the checkbox. - $this->trigger_on_change(); } } @@ -103,17 +97,4 @@ class behat_form_checkbox extends behat_form_field { return false; } - - /** - * Trigger on change event. - */ - protected function trigger_on_change() { - $driver = $this->session->getDriver(); - if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) { - $driver->triggerSynScript( - $this->field->getXPath(), - "Syn.trigger('change', {}, {{ELEMENT}})" - ); - } - } } diff --git a/lib/behat/form_field/behat_form_select.php b/lib/behat/form_field/behat_form_select.php index 071c0d40595..26e646f165c 100644 --- a/lib/behat/form_field/behat_form_select.php +++ b/lib/behat/form_field/behat_form_select.php @@ -67,35 +67,6 @@ class behat_form_select extends behat_form_field { // By default, assume the passed value is a non-multiple option. $this->field->selectOption(trim($value)); } - - // Wait for all the possible AJAX requests that have been - // already triggered by selectOption() to be finished. - if ($this->running_javascript()) { - // Trigger change event and click on first skip link, as some OS/browsers (Phantomjs, Mac-FF), - // don't close select option field and trigger event. - if (!$singleselect) { - $dialoguexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue-focused ')]"; - if (!$node = $this->session->getDriver()->find($dialoguexpath)) { - $script = "Syn.trigger('change', {}, {{ELEMENT}})"; - try { - $driver = $this->session->getDriver(); - if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) { - $driver->triggerSynScript($this->field->getXpath(), $script); - } - $driver->click('//body//div[@class="skiplinks"]'); - } catch (\Exception $e) { - return; - } - } else { - try { - $this->session->getDriver()->click($dialoguexpath); - } catch (\Exception $e) { - return; - } - } - } - $this->session->wait(behat_base::get_timeout() * 1000, behat_base::PAGE_READY_JS); - } } /** From 73e428979d574d6397441a47e8f927a0d076ee2a Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 09:29:14 +0800 Subject: [PATCH 15/26] MDL-66979 behat: Whitespace fix --- lib/behat/form_field/behat_form_select.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/behat/form_field/behat_form_select.php b/lib/behat/form_field/behat_form_select.php index 26e646f165c..228a5b614b5 100644 --- a/lib/behat/form_field/behat_form_select.php +++ b/lib/behat/form_field/behat_form_select.php @@ -64,7 +64,7 @@ class behat_form_select extends behat_form_field { $afterfirstoption = true; } } else { - // By default, assume the passed value is a non-multiple option. + // By default, assume the passed value is a non-multiple option. $this->field->selectOption(trim($value)); } } From 767c5f45128fb4a3c9e6e29a20e2205c45390181 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 09:29:59 +0800 Subject: [PATCH 16/26] MDL-66979 behat: Remove unused var --- lib/behat/form_field/behat_form_select.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/behat/form_field/behat_form_select.php b/lib/behat/form_field/behat_form_select.php index 228a5b614b5..10df8eafb58 100644 --- a/lib/behat/form_field/behat_form_select.php +++ b/lib/behat/form_field/behat_form_select.php @@ -51,7 +51,6 @@ class behat_form_select extends behat_form_field { // Is the select multiple? $multiple = $this->field->hasAttribute('multiple'); - $singleselect = ($this->field->hasClass('singleselect') || $this->field->hasClass('urlselect')); // Here we select the option(s). if ($multiple) { From 7984048d45f8062915327c3b213977a69672e1fa Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 09:30:18 +0800 Subject: [PATCH 17/26] MDL-66979 behat: Switch to generators These steps were creating content manually in an unnecessary fashion. I had to debug some issues with features in these areas so took the time to update them to make use of data generators, which are significantly faster. --- .../tests/behat/structural_changes.feature | 101 ++++++++++-------- .../tests/behat/grading_app_filters.feature | 81 ++++++-------- .../behat/discussion_subscriptions.feature | 101 +++++++++++------- user/tests/behat/enrol_cohort_list.feature | 28 ++--- 4 files changed, 161 insertions(+), 150 deletions(-) diff --git a/blocks/recent_activity/tests/behat/structural_changes.feature b/blocks/recent_activity/tests/behat/structural_changes.feature index 62dc4904017..ea4cba18306 100644 --- a/blocks/recent_activity/tests/behat/structural_changes.feature +++ b/blocks/recent_activity/tests/behat/structural_changes.feature @@ -46,49 +46,46 @@ Feature: View structural changes in recent activity block | GG3 | G2 | Scenario: Check that Added module information is displayed respecting view capability - Given I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I add the "Recent activity" block - When I add a "Forum" to section "1" and I fill the form with: - | name | ForumVisibleGroups | - | Description | No description | - | groupmode | Visible groups | - And I add a "Forum" to section "1" and I fill the form with: - | name | ForumSeparateGroups | - | Description | No description | - | groupmode | Separate groups | - And I add a "Forum" to section "1" and I fill the form with: - | name | ForumHidden | - | Description | No description | - | Availability | 0 | - And I add a "Forum" to section "1" and I fill the form with: - | name | ForumNoGroups | - | Description | No description | - | groupmode | No groups | - And I add a "Forum" to section "2" and I fill the form with: - | name | ForumVisibleGroupsG1 | - | Description | No description | - | groupmode | Visible groups | - | Grouping | Grouping 1 | + Given the following "activities" exist: + | activity | course | section | name | idnumber | description | groupmode | grouping | visible | + | forum | C1 | 1 | ForumVisibleGroups | forum1 | No description | 2 | | 1 | + | forum | C1 | 1 | ForumSeparateGroups | forum2 | No description | 1 | | 1 | + | forum | C1 | 1 | ForumHidden | forum3 | No description | 1 | | 0 | + | forum | C1 | 1 | ForumNoGroups | forum4 | No description | 0 | | 1 | + | forum | C1 | 2 | ForumVisibleGroupsG1 | forum5 | No description | 2 | GG1 | 1 | + | forum | C1 | 2 | ForumSeparateGroupsG1 | forum6 | No description | 1 | GG1 | 1 | + | forum | C1 | 3 | ForumVisibleGroupsG2 | forum7 | No description | 2 | GG2 | 1 | + | forum | C1 | 3 | ForumSeparateGroupsG2 | forum8 | No description | 1 | GG2 | 1 | + And I log in as "teacher1" + + And I am on "Course 1" course homepage + And I click on "ForumVisibleGroupsG1" "link" + And I click on "Edit settings" "link" + And I set the following fields to these values: | Access restrictions | Grouping: Grouping 1 | - And I add a "Forum" to section "2" and I fill the form with: - | name | ForumSeparateGroupsG1 | - | Description | No description | - | groupmode | Separate groups | - | Grouping | Grouping 1 | - | Access restrictions | Grouping: Grouping 1 | - And I add a "Forum" to section "3" and I fill the form with: - | name | ForumVisibleGroupsG2 | - | Description | No description | - | groupmode | Visible groups | - | Grouping | Grouping 2 | + And I press "Save and return to course" + + And I click on "ForumSeparateGroupsG1" "link" + And I click on "Edit settings" "link" + And I set the following fields to these values: + | Access restrictions | Grouping: Grouping 1 | + And I press "Save and return to course" + + And I click on "ForumVisibleGroupsG2" "link" + And I click on "Edit settings" "link" + And I set the following fields to these values: | Access restrictions | Grouping: Grouping 2 | - And I add a "Forum" to section "3" and I fill the form with: - | name | ForumSeparateGroupsG2 | - | Description | No description | - | groupmode | Separate groups | - | Grouping | Grouping 2 | - | Access restrictions | Grouping: Grouping 2 | + And I press "Save and return to course" + + And I click on "ForumSeparateGroupsG2" "link" + And I click on "Edit settings" "link" + And I set the following fields to these values: + | Access restrictions | Grouping: Grouping 2 | + And I press "Save and return to course" + + And I am on "Course 1" course homepage with editing mode on + When I add the "Recent activity" block + Then I should see "ForumVisibleGroups" in the "Recent activity" "block" And I should see "ForumSeparateGroups" in the "Recent activity" "block" And I should see "ForumNoGroups" in the "Recent activity" "block" @@ -98,6 +95,7 @@ Feature: View structural changes in recent activity block And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block" And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block" And I log out + And I log in as "student1" And I am on "Course 1" course homepage And I should see "ForumVisibleGroups" in the "Recent activity" "block" @@ -109,6 +107,7 @@ Feature: View structural changes in recent activity block And I should not see "ForumVisibleGroupsG2" in the "Recent activity" "block" And I should not see "ForumSeparateGroupsG2" in the "Recent activity" "block" And I log out + And I log in as "student2" And I am on "Course 1" course homepage And I should see "ForumVisibleGroups" in the "Recent activity" "block" @@ -120,6 +119,7 @@ Feature: View structural changes in recent activity block And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block" And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block" And I log out + And I log in as "student3" And I am on "Course 1" course homepage And I should see "ForumVisibleGroups" in the "Recent activity" "block" @@ -131,6 +131,7 @@ Feature: View structural changes in recent activity block And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block" And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block" And I log out + # Teachers have capability to see all groups and hidden activities And I log in as "assistant1" And I am on "Course 1" course homepage @@ -142,15 +143,20 @@ Feature: View structural changes in recent activity block And I log out Scenario: Updates and deletes in recent activity block + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | ForumNew | + | description | No description | When I log in as "teacher1" And I am on "Course 1" course homepage with editing mode on And I add the "Recent activity" block - And I add a "Forum" to section "1" and I fill the form with: - | name | ForumNew | - | Description | No description | Then I should see "Added Forum" in the "Recent activity" "block" And I should see "ForumNew" in the "Recent activity" "block" And I log out + + # Update forum as a teacher after a second to ensure we have a new timestamp for recent activity. And I wait "1" seconds And I log in as "student1" And I am on "Course 1" course homepage @@ -159,6 +165,7 @@ Feature: View structural changes in recent activity block And I log out # Update forum as a teacher after a second to ensure we have a new timestamp for recent activity. And I wait "1" seconds + # Update forum as a teacher And I log in as "teacher1" And I am on "Course 1" course homepage @@ -170,6 +177,7 @@ Feature: View structural changes in recent activity block And I log out And I wait "1" seconds # Student 1 already saw that forum was created, now he can see that forum was updated + And I log in as "student1" And I am on "Course 1" course homepage And I should not see "Added Forum" in the "Recent activity" "block" @@ -179,6 +187,7 @@ Feature: View structural changes in recent activity block And I log out And I wait "1" seconds # Student 2 has bigger interval and he can see one entry that forum was created but with the new name + And I log in as "student2" And I am on "Course 1" course homepage And I should see "Added Forum" in the "Recent activity" "block" @@ -188,6 +197,7 @@ Feature: View structural changes in recent activity block And I log out And I wait "1" seconds # Delete forum as a teacher + And I log in as "teacher1" And I am on "Course 1" course homepage with editing mode on And I delete "ForumUpdated" activity @@ -195,6 +205,7 @@ Feature: View structural changes in recent activity block And I log out And I wait "1" seconds # Students 1 and 2 see that forum was deleted + And I log in as "student1" And I am on "Course 1" course homepage And I should not see "Added Forum" in the "Recent activity" "block" @@ -205,6 +216,7 @@ Feature: View structural changes in recent activity block And I log out And I wait "1" seconds # Student 3 never knew that forum was created, so he does not see anything + And I log in as "student3" And I am on "Course 1" course homepage And I should not see "Added Forum" in the "Recent activity" "block" @@ -212,4 +224,3 @@ Feature: View structural changes in recent activity block And I should not see "Updated Forum" in the "Recent activity" "block" And I should not see "ForumUpdated" in the "Recent activity" "block" And I should not see "Deleted Forum" in the "Recent activity" "block" - And I log out diff --git a/mod/assign/tests/behat/grading_app_filters.feature b/mod/assign/tests/behat/grading_app_filters.feature index 293d0e96dda..e9f6908a195 100644 --- a/mod/assign/tests/behat/grading_app_filters.feature +++ b/mod/assign/tests/behat/grading_app_filters.feature @@ -4,34 +4,39 @@ Feature: In an assignment, teachers can change filters in the grading app As a teacher I need to preserve filter settings between the grader app and grading table. - @javascript - Scenario: Set filters in the grading table and see them in the grading app + Background: Given the following "courses" exist: | fullname | shortname | category | groupmode | - | Course 1 | C1 | 0 | 1 | + | Course 1 | C1 | 0 | 1 | And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | marker1 | Marker | 1 | marker1@example.com | - | marker2 | Marker | 2 | marker2@example.com | + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + | marker1 | Marker | 1 | marker1@example.com | + | marker2 | Marker | 2 | marker2@example.com | And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - | marker1 | C1 | teacher | - | marker2 | C1 | teacher | - And I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I add a "Assignment" to section "1" and I fill the form with: - | Assignment name | Test assignment name | - | Description | Submit your online text | - | assignsubmission_onlinetext_enabled | 1 | - | assignsubmission_file_enabled | 0 | - | Use marking workflow | Yes | - | Use marking allocation | Yes | + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | marker1 | C1 | teacher | + | marker2 | C1 | teacher | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | name | Test assignment name | + | idnumber | assign | + | description | Submit your online text | + | assignsubmission_onlinetext_enabled | 1 | + | assignsubmission_file_enabled | 0 | + | markingworkflow | 1 | + | markingallocation | 1 | + + @javascript + Scenario: Set filters in the grading table and see them in the grading app + Given I log in as "teacher1" + And I am on "Course 1" course homepage And I follow "Test assignment name" And I navigate to "View all submissions" in current page administration And I click on "Grade" "link" in the "Student 1" "table_row" @@ -55,32 +60,8 @@ Feature: In an assignment, teachers can change filters in the grading app @javascript Scenario: Set filters in the grading app and see them in the grading table - Given the following "courses" exist: - | fullname | shortname | category | groupmode | - | Course 1 | C1 | 0 | 1 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | marker1 | Marker | 1 | marker1@example.com | - | marker2 | Marker | 2 | marker2@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - | marker1 | C1 | teacher | - | marker2 | C1 | teacher | - And I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I add a "Assignment" to section "1" and I fill the form with: - | Assignment name | Test assignment name | - | Description | Submit your online text | - | assignsubmission_onlinetext_enabled | 1 | - | assignsubmission_file_enabled | 0 | - | Use marking workflow | Yes | - | Use marking allocation | Yes | + Given I log in as "teacher1" + And I am on "Course 1" course homepage And I follow "Test assignment name" And I navigate to "View all submissions" in current page administration And I click on "Grade" "link" in the "Student 1" "table_row" diff --git a/mod/forum/tests/behat/discussion_subscriptions.feature b/mod/forum/tests/behat/discussion_subscriptions.feature index 212b724abaa..2ba4f0a707b 100644 --- a/mod/forum/tests/behat/discussion_subscriptions.feature +++ b/mod/forum/tests/behat/discussion_subscriptions.feature @@ -15,15 +15,18 @@ Feature: A user can control their own subscription preferences for a discussion | user | course | role | | student1 | C1 | student | And I log in as "admin" - And I am on "Course 1" course homepage with editing mode on @javascript Scenario: An optional forum can have discussions subscribed to - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Optional subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 0 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | @@ -62,11 +65,15 @@ Feature: A user can control their own subscription preferences for a discussion @javascript Scenario: An automatic subscription forum can have discussions unsubscribed from - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Auto subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 2 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | @@ -105,11 +112,15 @@ Feature: A user can control their own subscription preferences for a discussion @javascript Scenario: A user does not lose their preferences when a forum is switch from optional to automatic - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Optional subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 0 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | @@ -150,11 +161,15 @@ Feature: A user can control their own subscription preferences for a discussion @javascript Scenario: A user does not lose their preferences when a forum is switch from optional to automatic - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Optional subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 0 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | @@ -194,11 +209,15 @@ Feature: A user can control their own subscription preferences for a discussion And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row" Scenario: An optional forum prompts a user to subscribe to a discussion when posting unless they have already chosen not to subscribe - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Optional subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 0 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | @@ -230,11 +249,15 @@ Feature: A user can control their own subscription preferences for a discussion And the field "Discussion subscription" matches value "I don't want to be notified of new posts in this discussion" Scenario: An automatic forum prompts a user to subscribe to a discussion when posting unless they have already chosen not to subscribe - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Auto subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 2 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | @@ -267,6 +290,7 @@ Feature: A user can control their own subscription preferences for a discussion Scenario: A guest should not be able to subscribe to a discussion Given I am on site homepage + And I turn editing mode on And I add a "Forum" to section "1" and I fill the form with: | Forum name | Test forum name | | Forum type | Standard forum for general use | @@ -285,6 +309,7 @@ Feature: A user can control their own subscription preferences for a discussion Scenario: A user who is not logged in should not be able to subscribe to a discussion Given I am on site homepage + And I turn editing mode on And I add a "Forum" to section "1" and I fill the form with: | Forum name | Test forum name | | Forum type | Standard forum for general use | @@ -301,11 +326,15 @@ Feature: A user can control their own subscription preferences for a discussion And "Unsubscribe from this discussion" "checkbox" should not exist Scenario: A user can toggle their subscription preferences when viewing a discussion - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Subscription mode | Optional subscription | + Given the following "activity" exists: + | activity | forum | + | course | C1 | + | idnumber | forum1 | + | name | Test forum name | + | intro | Test forum description | + | type | general | + | forcesubscribe | 0 | + And I am on "Course 1" course homepage And I add a new discussion to "Test forum name" forum with: | Subject | Test post subject one | | Message | Test post message one | diff --git a/user/tests/behat/enrol_cohort_list.feature b/user/tests/behat/enrol_cohort_list.feature index 305cedf16da..f19813c045e 100644 --- a/user/tests/behat/enrol_cohort_list.feature +++ b/user/tests/behat/enrol_cohort_list.feature @@ -17,19 +17,15 @@ Feature: Viewing the list of cohorts to enrol in a course @javascript Scenario: Check the teacher does not see the cohorts field without the proper capabilities - Given I log in as "admin" + Given the following "cohort" exists: + | name | Test cohort name | + | idnumber | 1337 | + | description | Test cohort description | + And I log in as "admin" And I set the following system permissions of "Teacher" role: | capability | permission | | moodle/cohort:manage | Prohibit | | moodle/cohort:view | Prohibit | - And I navigate to "Users > Accounts >Cohorts" in site administration - And I follow "Add new cohort" - And I set the following fields to these values: - | Name | Test cohort name | - | Context | System | - | Cohort ID | 1337 | - | Description | Test cohort description | - And I press "Save changes" And I log out And I log in as "teacher1" And I am on "Course 1" course homepage @@ -40,16 +36,10 @@ Feature: Viewing the list of cohorts to enrol in a course @javascript Scenario: Check we show the cohorts field if there are some present - Given I log in as "admin" - And I navigate to "Users > Accounts >Cohorts" in site administration - And I follow "Add new cohort" - And I set the following fields to these values: - | Name | Test cohort name | - | Context | System | - | Cohort ID | 1337 | - | Description | Test cohort description | - And I press "Save changes" - And I log out + Given the following "cohort" exists: + | name | Test cohort name | + | idnumber | 1337 | + | description | Test cohort description | And I log in as "teacher1" And I am on "Course 1" course homepage And I navigate to course participants From 5e077b8a2b5f1bc045fca08316172f79456642a2 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 09:28:55 +0800 Subject: [PATCH 18/26] MDL-66979 mod_assign: Stop clicking the user filters Remove the documented hack which was re-opening a popup because it "closes for some reason". It no longer randomly closes. --- mod/assign/tests/behat/grading_app_filters.feature | 2 -- 1 file changed, 2 deletions(-) diff --git a/mod/assign/tests/behat/grading_app_filters.feature b/mod/assign/tests/behat/grading_app_filters.feature index e9f6908a195..0fec2c2c3ca 100644 --- a/mod/assign/tests/behat/grading_app_filters.feature +++ b/mod/assign/tests/behat/grading_app_filters.feature @@ -78,8 +78,6 @@ Feature: In an assignment, teachers can change filters in the grading app And I click on "Grade" "link" in the "Student 1" "table_row" And I click on "[data-region=user-filters]" "css_element" And I set the field "filter" to "Not submitted" - # The popup closes for some reason, so it needs to be reopened. - And I click on "[data-region=user-filters]" "css_element" And I set the field "markerfilter" to "Marker 1" And I set the field "workflowfilter" to "In marking" And I click on "View all submissions" "link" From dabca5c457b0ec2f8e0eb32902958a7372795ea8 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 10:10:57 +0800 Subject: [PATCH 19/26] MDL-66979 question: Improve behat test reliability Expand all fieldsets rather than individual fieldsets. This can fail in some situations where the page moves as the first fieldset opens and HTML transitions take effect. This causes subsequent fieldsets to move after WebDriver has calculated the click target. --- question/type/ddmarker/tests/behat/add.feature | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/question/type/ddmarker/tests/behat/add.feature b/question/type/ddmarker/tests/behat/add.feature index 733e457233d..ec506c2d85b 100644 --- a/question/type/ddmarker/tests/behat/add.feature +++ b/question/type/ddmarker/tests/behat/add.feature @@ -27,16 +27,15 @@ Feature: Test creating a drag and drop markers question And I set the field "Question text" to "Please place the markers on the map of Milton Keynes and be aware that there is more than one railway station." And I set the field "General feedback" to "The Open University is at the junction of Brickhill Street and Groveway. There are three railway stations, Wolverton, Milton Keynes Central and Bletchley." And I upload "question/type/ddmarker/tests/fixtures/mkmap.png" file to "Background image" filemanager + And I expand all fieldsets # Markers. - And I follow "Markers" And I set the field "id_drags_0_label" to "OU" And I set the field "id_drags_0_noofdrags" to "1" And I set the field "id_drags_1_label" to "Railway station" And I set the field "id_drags_1_noofdrags" to "3" # Drop zones. - And I follow "Drop zones" And I set the field "id_drops_0_shape" to "Circle" And I set the field "id_drops_0_coords" to "322,213;10" And I set the field "id_drops_0_choice" to "1" From c56395fba6bc0bbd4fe0a90976c9f4776819b11c Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 14:20:31 +0800 Subject: [PATCH 20/26] MDL-66979 behat: Improve chromeOptions configuration Simplify the chromeOptions configuration to improve readability. --- lib/behat/classes/behat_config_util.php | 37 +++++++++++++++---------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/behat/classes/behat_config_util.php b/lib/behat/classes/behat_config_util.php index a7774410b0a..2ddfc640361 100644 --- a/lib/behat/classes/behat_config_util.php +++ b/lib/behat/classes/behat_config_util.php @@ -634,20 +634,21 @@ class behat_config_util { // We also need to disable web security, otherwise it can't make CSS requests to the server // on localhost due to CORS restrictions. if (!empty($values['browser']) && $values['browser'] === 'chrome') { - if (!isset($values['capabilities'])) { - $values['capabilities'] = []; - } - if (!isset($values['capabilities']['extra_capabilities'])) { - $values['capabilities']['extra_capabilities'] = []; - } - if (!isset($values['capabilities']['extra_capabilities']['chromeOptions'])) { - $values['capabilities']['extra_capabilities']['chromeOptions'] = []; - } - if (!isset($values['capabilities']['extra_capabilities']['chromeOptions']['args'])) { - $values['capabilities']['extra_capabilities']['chromeOptions']['args'] = []; - } - $values['capabilities']['extra_capabilities']['chromeOptions']['args'][] = '--unlimited-storage'; - $values['capabilities']['extra_capabilities']['chromeOptions']['args'][] = '--disable-web-security'; + $values = array_merge_recursive( + [ + 'capabilities' => [ + 'extra_capabilities' => [ + 'chromeOptions' => [ + 'args' => [ + 'unlimited-storage', + 'disable-web-security', + ], + ], + ], + ], + ], + $values + ); // If the mobile app is enabled, check its version and add appropriate tags. if ($mobiletags = $this->get_mobile_version_tags()) { @@ -657,6 +658,14 @@ class behat_config_util { $values['tags'] = $mobiletags; } } + + $values['capabilities']['extra_capabilities']['chromeOptions']['args'] = array_map(function($arg): string { + if (substr($arg, 0, 2) === '--') { + return substr($arg, 2); + } + return $arg; + }, $values['capabilities']['extra_capabilities']['chromeOptions']['args']); + sort($values['capabilities']['extra_capabilities']['chromeOptions']['args']); } // Fill tags information. From ce30baea5961558ccfd5fbca0f121eb82f98bf90 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 13 Nov 2020 14:20:57 +0800 Subject: [PATCH 21/26] MDL-66979 behat: availability field extends textarea The availability behat field extends the textarea type, and therefore needs to include this type. --- lib/behat/form_field/behat_form_availability.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/behat/form_field/behat_form_availability.php b/lib/behat/form_field/behat_form_availability.php index 54f38fd3ed6..fb9c7eedd50 100644 --- a/lib/behat/form_field/behat_form_availability.php +++ b/lib/behat/form_field/behat_form_availability.php @@ -25,7 +25,7 @@ // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. -require_once(__DIR__ . '/behat_form_field.php'); +require_once(__DIR__ . '/behat_form_textarea.php'); /** * Availability form field class. From 30e2579222de90195aa46c45f2f3a1fcb268e6ce Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 17 Nov 2020 20:02:01 +0800 Subject: [PATCH 22/26] MDL-66979 behat: Work around weird gradebook focus behaviour I can't expand this one in a sane fashion but the older JS is doing some weird and wonderful things with focus. The only way I could get this to behave correctly was to move away from the field, move back to it, and then move away again. Other combinations failed in different browsers for different reasons. --- grade/report/grader/tests/behat/ajax_grader.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grade/report/grader/tests/behat/ajax_grader.feature b/grade/report/grader/tests/behat/ajax_grader.feature index 3500be14ba0..431091fef47 100644 --- a/grade/report/grader/tests/behat/ajax_grader.feature +++ b/grade/report/grader/tests/behat/ajax_grader.feature @@ -65,6 +65,8 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe And I click on student "Student 3" for grade item "Item SU" And I set the field "ajaxgrade" to "Very good" And I press the shift tab key + And I press the tab key + And I press the shift tab key And I click on student "Student 3" for grade item "Item VU" And I set the field "ajaxgrade" to "50" And I press the enter key From d44fdcf54cd1b0e97e401599da4dea18781363d4 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 8 Dec 2020 14:47:58 +0800 Subject: [PATCH 23/26] MDL-66979 behat: Pad messaging drawer This works around an issue highlighted by MDL-70411 whereby some of the messaging links are covered by the scrollbar in Firefox on MacOS. --- theme/boost/scss/moodle/debug.scss | 7 +++++++ theme/boost/style/moodle.css | 3 +++ theme/classic/style/moodle.css | 3 +++ 3 files changed, 13 insertions(+) diff --git a/theme/boost/scss/moodle/debug.scss b/theme/boost/scss/moodle/debug.scss index a534c9cbfbc..9f1f0745c74 100644 --- a/theme/boost/scss/moodle/debug.scss +++ b/theme/boost/scss/moodle/debug.scss @@ -40,6 +40,13 @@ body.behat-site { content: none; } } + + // Workaround for MDL-70411. + // Pad the side of the message drawer out slightly to ensure that Firefox scroll bar does not cover controls at the + // edge of the screen. + [data-region="message-drawer"] { + padding-right: 10px; + } } .phpinfo table, diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index ead8d43b82b..02b836fcedc 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -18769,6 +18769,9 @@ body.behat-site .custom-control-input { body.behat-site .custom-control-label::before, body.behat-site .custom-control-label::after { content: none; } +body.behat-site [data-region="message-drawer"] { + padding-right: 10px; } + .phpinfo table, .phpinfo th, .phpinfo h2 { diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index 4f597056f82..72f45198178 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -18950,6 +18950,9 @@ body.behat-site .custom-control-input { body.behat-site .custom-control-label::before, body.behat-site .custom-control-label::after { content: none; } +body.behat-site [data-region="message-drawer"] { + padding-right: 10px; } + .phpinfo table, .phpinfo th, .phpinfo h2 { From 5282a676154badb5d411d30bc45230dc6e5a155f Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 16 Dec 2020 15:42:57 +0800 Subject: [PATCH 24/26] MDL-66979 behat: Uncomment step disabled for old firefox --- admin/tool/behat/tests/behat/keyboard.feature | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/admin/tool/behat/tests/behat/keyboard.feature b/admin/tool/behat/tests/behat/keyboard.feature index cdcb0812f4f..ca9a74f02f3 100644 --- a/admin/tool/behat/tests/behat/keyboard.feature +++ b/admin/tool/behat/tests/behat/keyboard.feature @@ -28,16 +28,15 @@ Feature: Verify that keyboard steps work as expected And I press the shift tab key And the focused element is "Username" "field" -# TODO: Uncomment the following when MDL-66979 is integrated. -# @javascript -# Scenario: Using the arrow keys allows me to navigate through menus -# Given the following "users" exist: -# | username | email | firstname | lastname | -# | saffronr | saffron.rutledge@example.com | Saffron | Rutledge | -# And I log in as "saffronr" -# And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element" -# When I press the up key -# Then the focused element is "Log out" "link" + @javascript + Scenario: Using the arrow keys allows me to navigate through menus + Given the following "users" exist: + | username | email | firstname | lastname | + | saffronr | saffron.rutledge@example.com | Saffron | Rutledge | + And I log in as "saffronr" + And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element" + When I press the up key + Then the focused element is "Log out" "link" @javascript Scenario: The escape key can be used to close a dialogue From ef4a652abed0387e44fb3eaaa7998d29d9719b9b Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 22 Jan 2021 13:26:16 +0800 Subject: [PATCH 25/26] MDL-66979 behat: Rename and warn on old config --- lib/behat/classes/behat_config_util.php | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/behat/classes/behat_config_util.php b/lib/behat/classes/behat_config_util.php index 2ddfc640361..886a74caf89 100644 --- a/lib/behat/classes/behat_config_util.php +++ b/lib/behat/classes/behat_config_util.php @@ -931,6 +931,7 @@ class behat_config_util { // In case user defined overrides respect them over our default ones. if (!empty($CFG->behat_config)) { foreach ($CFG->behat_config as $profile => $values) { + $values = $this->fix_legacy_profile_data($profile, $values); $config = $this->merge_config($config, $this->get_behat_config_for_profile($profile, $values)); } } @@ -1000,6 +1001,35 @@ class behat_config_util { return $config; } + /** + * Check for and attempt to fix legacy profile data. + * + * The Mink Driver used for W3C no longer uses the `selenium2` naming but otherwise is backwards compatibly. + * + * Emit a warning that users should update their configuration. + * + * @param string $profilename The name of this profile + * @param array $data The profile data for this profile + * @return array Th eamended profile data + */ + protected function fix_legacy_profile_data(string $profilename, array $data): array { + // Check for legacy instaclick profiles. + if (!array_key_exists('Behat\MinkExtension', $data['extensions'])) { + return $data; + } + if (array_key_exists('selenium2', $data['extensions']['Behat\MinkExtension'])) { + echo("\n\n"); + echo("=> Warning: Legacy selenium2 profileuration was found for {$profilename} profile.\n"); + echo("=> This has been renamed from 'selenium2' to 'webdriver'.\n"); + echo("=> You should update your Behat configuration.\n"); + echo("\n"); + $data['extensions']['Behat\MinkExtension']['webdriver'] = $data['extensions']['Behat\MinkExtension']['selenium2']; + unset($data['extensions']['Behat\MinkExtension']['selenium2']); + } + + return $data; + } + /** * Cleans the path returned by get_components_with_tests() to standarize it * From 058394a41285d0682d69295f8f0c155dd760d904 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Sat, 23 Jan 2021 20:43:20 +0800 Subject: [PATCH 26/26] MDL-66979 behat: Warn about old behat.yml file location --- admin/tool/behat/lang/en/tool_behat.php | 1 + lib/behat/classes/behat_command.php | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/admin/tool/behat/lang/en/tool_behat.php b/admin/tool/behat/lang/en/tool_behat.php index eea7b519d98..01c607d11dd 100644 --- a/admin/tool/behat/lang/en/tool_behat.php +++ b/admin/tool/behat/lang/en/tool_behat.php @@ -46,6 +46,7 @@ $string['stepsdefinitionstype'] = 'Type'; $string['theninfo'] = 'Then. Checkings to ensure the outcomes are the expected ones'; $string['unknownexceptioninfo'] = 'There was a problem with Selenium or your browser. Please ensure you are using the latest version of Selenium. Error:'; $string['viewsteps'] = 'Filter'; +$string['warndirrootconfigfound'] = 'A configuration file was found at {$a}. This file is not automatically updated and may become stale. We recommend removing this file.'; $string['wheninfo'] = 'When. Action that provokes an event'; $string['wrongbehatsetup'] = 'Something is wrong with the behat setup and so step definitions cannot be listed: {$a->errormsg}

Please check:
  • $CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot are set in config.php with different values from $CFG->dataroot, $CFG->prefix and $CFG->wwwroot.
  • diff --git a/lib/behat/classes/behat_command.php b/lib/behat/classes/behat_command.php index 4adc6275ee3..64ce8f6de77 100644 --- a/lib/behat/classes/behat_command.php +++ b/lib/behat/classes/behat_command.php @@ -179,7 +179,11 @@ class behat_command { } // Behat test command. - list($output, $code) = self::run(' --help'); + $dirrootconfigpath = $CFG->dirroot . DIRECTORY_SEPARATOR . 'behat.yml'; + if (file_exists($dirrootconfigpath)) { + self::output_msg(get_string('warndirrootconfigfound', 'tool_behat', $dirrootconfigpath)); + } + list($output, $code) = self::run(" --help"); if ($code != 0) {