diff --git a/public/lib/behat/classes/behat_session_trait.php b/public/lib/behat/classes/behat_session_trait.php index 9efda2210f1..8394c346a89 100644 --- a/public/lib/behat/classes/behat_session_trait.php +++ b/public/lib/behat/classes/behat_session_trait.php @@ -28,13 +28,14 @@ use Behat\Mink\Element\Element; use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; use Behat\Mink\Exception\ElementNotFoundException; -use Behat\Mink\Exception\NoSuchWindowException; use Behat\Mink\Session; use Behat\Testwork\Hook\Scope\HookScope; +use Facebook\WebDriver\Exception\NoSuchWindowException; use Facebook\WebDriver\Exception\ScriptTimeoutException; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\WebDriverElement; +// phpcs:disable moodle.Files.MoodleInternal.MoodleInternalGlobalState // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. require_once(__DIR__ . '/component_named_replacement.php'); @@ -57,7 +58,6 @@ class_alias('Facebook\WebDriver\WebDriverKeys', 'behat_keys'); * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ trait behat_session_trait { - /** * Locates url, based on provided path. * Override to provide custom routing mechanism. @@ -110,7 +110,7 @@ trait behat_session_trait { // Throw exception, so dev knows it is not supported. if ($selector === 'named') { $exception = 'Using the "named" selector is deprecated as of 3.1. ' - .' Use the "named_partial" or use the "named_exact" selector instead.'; + . ' Use the "named_partial" or use the "named_exact" selector instead.'; throw new ExpectationException($exception, $this->getSession()); } @@ -125,7 +125,6 @@ trait behat_session_trait { if ($this->running_javascript()) { $locator[1] = html_entity_decode($locator[1], ENT_NOQUOTES); } - } else { $exceptiontype = $selector; $exceptionlocator = $locator; @@ -154,9 +153,13 @@ trait behat_session_trait { // Waits for the node to appear if it exists, otherwise will timeout and throw the provided exception. return $this->spin( - function() use ($selector, $locator, $container) { + function () use ($selector, $locator, $container) { return $container->findAll($selector, $locator); - }, [], $timeout, $exception, $microsleep + }, + [], + $timeout, + $exception, + $microsleep ); } @@ -194,11 +197,13 @@ trait behat_session_trait { if ($converttonamed) { if (behat_partial_named_selector::is_deprecated_selector($selector)) { if ($replacement = behat_partial_named_selector::get_deprecated_replacement($selector)) { + // phpcs:ignore moodle.PHP.ForbiddenFunctions.FoundWithAlternative error_log("The '{$selector}' selector has been replaced with {$replacement}"); $selector = $replacement; } } else if (behat_exact_named_selector::is_deprecated_selector($selector)) { if ($replacement = behat_exact_named_selector::get_deprecated_replacement($selector)) { + // phpcs:ignore moodle.PHP.ForbiddenFunctions.FoundWithAlternative error_log("The '{$selector}' selector has been replaced with {$replacement}"); $selector = $replacement; } @@ -213,7 +218,10 @@ trait behat_session_trait { $locator = behat_selectors::normalise_named_selector($allowedexactselectors[$selector], $locator); $selector = 'named_exact'; } else { - throw new ExpectationException("The '{$selector}' selector type is not registered.", $this->getSession()->getDriver()); + throw new ExpectationException( + "The '{$selector}' selector type is not registered.", + $this->getSession()->getDriver(), + ); } } @@ -384,7 +392,6 @@ trait behat_session_trait { } usleep(100000); - } while (microtime(true) < $end); // Using coding_exception as is a development issue if no exception has been provided. @@ -420,7 +427,7 @@ trait behat_session_trait { */ protected function get_text_selector_node($selectortype, $element) { // Getting Mink selector and locator. - list($selector, $locator) = $this->transform_text_selector($selectortype, $element); + [$selector, $locator] = $this->transform_text_selector($selectortype, $element); // Returns the NodeElement. return $this->find($selector, $locator); @@ -496,7 +503,10 @@ trait behat_session_trait { $selectors = behat_selectors::get_allowed_text_selectors(); if (empty($selectors[$selectortype])) { - throw new ExpectationException('The "' . $selectortype . '" selector can not be used to select text nodes', $this->getSession()); + throw new ExpectationException( + "The \"{$selectortype}\" selector can not be used to select text nodes", + $this->getSession(), + ); } return $this->transform_selector($selectortype, $element); @@ -587,7 +597,7 @@ trait behat_session_trait { // It will stop spinning once the find() method returns true. $this->spin( - function() use ($selector, $locator, $container) { + function () use ($selector, $locator, $container) { if ($container->find($selector, $locator)) { return true; } @@ -622,7 +632,7 @@ trait behat_session_trait { // It will stop spinning once the find() method returns false. $this->spin( - function() use ($selector, $locator, $container) { + function () use ($selector, $locator, $container) { if ($container->find($selector, $locator)) { return false; } @@ -655,7 +665,7 @@ trait behat_session_trait { // It will stop spinning once the isVisible() method returns true. $this->spin( - function($context, $args) { + function ($context, $args) { if ($args->isVisible()) { return true; } @@ -690,13 +700,13 @@ trait behat_session_trait { // It will stop spinning once the $args[1]) == $args[2], and method returns true. $this->spin( - function($context, $args) { + function ($context, $args) { if ($args[0]->getAttribute($args[1]) == $args[2]) { return true; } return false; }, - array($node, $attribute, $attributevalue), + [$node, $attribute, $attributevalue], self::get_extended_timeout(), $exception, true @@ -912,7 +922,6 @@ EOF; public function look_for_exceptions() { // Wrap in try in case we were interacting with a closed window. try { - // Exceptions. $exceptionsxpath = "//div[@data-rel='fatalerror']"; // Debugging messages. @@ -922,7 +931,7 @@ EOF; // Any other backtrace. $othersxpath = "(//*[contains(., ': call to ')])[1]"; - $xpaths = array($exceptionsxpath, $debuggingxpath, $phperrorxpath, $othersxpath); + $xpaths = [$exceptionsxpath, $debuggingxpath, $phperrorxpath, $othersxpath]; $joinedxpath = implode(' | ', $xpaths); // Joined xpath expression. Most of the time there will be no exceptions, so this pre-check @@ -933,7 +942,7 @@ EOF; if (!empty($phperrors)) { foreach ($phperrors as $error) { $errnostring = behat_get_error_string($error['type']); - $msgs[] = $errnostring . ": " .$error['message'] . " at " . $error['file'] . ": " . $error['line']; + $msgs[] = $errnostring . ": " . $error['message'] . " at " . $error['file'] . ": " . $error['line']; } $msg = "PHP errors found:\n" . implode("\n", $msgs); throw new \Exception(htmlentities($msg, ENT_COMPAT)); @@ -944,7 +953,6 @@ EOF; // Exceptions. if ($errormsg = $this->getSession()->getPage()->find('xpath', $exceptionsxpath)) { - // Getting the debugging info and the backtrace. $errorinfoboxes = $this->getSession()->getPage()->findAll('css', 'div.alert-error'); // If errorinfoboxes is empty, try find alert-danger (bootstrap4) class. @@ -964,7 +972,6 @@ EOF; if ($errorinfoboxes) { $errorinfo = $this->get_debug_text($errorinfoboxes[0]->getHtml()); } - } else { $errorinfo = implode("\n", [ $this->get_debug_text($errorinfoboxes[0]->getHtml()), @@ -979,7 +986,7 @@ EOF; // Debugging messages. if ($debuggingmessages = $this->getSession()->getPage()->findAll('xpath', $debuggingxpath)) { - $msgs = array(); + $msgs = []; foreach ($debuggingmessages as $debuggingmessage) { $msgs[] = $this->get_debug_text($debuggingmessage->getHtml()); } @@ -989,8 +996,7 @@ EOF; // PHP debug messages. if ($phpmessages = $this->getSession()->getPage()->findAll('xpath', $phperrorxpath)) { - - $msgs = array(); + $msgs = []; foreach ($phpmessages as $phpmessage) { $msgs[] = $this->get_debug_text($phpmessage->getHtml()); } @@ -1004,7 +1010,7 @@ EOF; if ($this->getSession()->getDriver()->find($othersxpath)) { $backtracespattern = '/(line [0-9]* of [^:]*: call to [\->&;:a-zA-Z_\x7f-\xff][\->&;:a-zA-Z0-9_\x7f-\xff]*)/'; if (preg_match_all($backtracespattern, $this->getSession()->getPage()->getContent(), $backtraces)) { - $msgs = array(); + $msgs = []; foreach ($backtraces[0] as $backtrace) { $msgs[] = $backtrace . '()'; } @@ -1012,9 +1018,10 @@ EOF; throw new \Exception(htmlentities($msg, ENT_COMPAT)); } } - + // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch } catch (NoSuchWindowException $e) { // If we were interacting with a popup window it will not exists after closing it. + // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch } catch (DriverException $e) { // Same reason as above. } @@ -1194,7 +1201,7 @@ EOF; } $session = \core\session\manager::get_session_by_sid($sid); if (empty($session->userid)) { - throw new coding_exception('failed to get user from session id: '.$sid); + throw new coding_exception('failed to get user from session id: ' . $sid); } return $DB->get_record('user', ['id' => $session->userid]); } @@ -1214,9 +1221,9 @@ EOF; $user = clone($user); } else if (!$user) { // Assign valid data to admin user (some generator-related code needs a valid user). - $user = $DB->get_record('user', array('username' => 'admin')); + $user = $DB->get_record('user', ['username' => 'admin']); } else { - $user = $DB->get_record('user', array('id' => $user)); + $user = $DB->get_record('user', ['id' => $user]); } unset($user->description); unset($user->access); diff --git a/public/lib/tests/behat/behat_general.php b/public/lib/tests/behat/behat_general.php index de35a590bd9..8e44148804b 100644 --- a/public/lib/tests/behat/behat_general.php +++ b/public/lib/tests/behat/behat_general.php @@ -52,25 +52,24 @@ use Facebook\WebDriver\WebDriverExpectedCondition; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class behat_general extends behat_base { - /** * @var string used by {@link switch_to_window()} and * {@link switch_to_the_main_window()} to work-around a Chrome browser issue. */ - const MAIN_WINDOW_NAME = '__moodle_behat_main_window_name'; + public const MAIN_WINDOW_NAME = '__moodle_behat_main_window_name'; /** * @var string when we want to check whether or not a new page has loaded, * we first write this unique string into the page. Then later, by checking * whether it is still there, we can tell if a new page has been loaded. */ - const PAGE_LOAD_DETECTION_STRING = 'new_page_not_loaded_since_behat_started_watching'; + public const PAGE_LOAD_DETECTION_STRING = 'new_page_not_loaded_since_behat_started_watching'; /** * @var $pageloaddetectionrunning boolean Used to ensure that page load detection was started before a page reload * was checked for. */ - private $pageloaddetectionrunning = false; + private bool $pageloaddetectionrunning = false; /** * Opens Moodle homepage. @@ -153,26 +152,21 @@ class behat_general extends behat_base { // Getting the refresh time and the url if present. if (strstr($content, 'url') != false) { - [$waittime, $url] = explode(';', $content); // Cleaning the URL value. $url = trim(substr($url, strpos($url, 'http'))); - } else { // Just wait then. $waittime = $content; } - // Wait until the URL change is executed. if ($this->running_javascript()) { $this->getSession()->wait($waittime * 1000); - } else if (!empty($url)) { // We redirect directly as we can not wait for an automatic redirection. $this->getSession()->getDriver()->getClient()->request('GET', $url); - } else { // Reload the page if no URL was provided. $this->getSession()->getDriver()->reload(); @@ -191,7 +185,7 @@ class behat_general extends behat_base { // Using extended timeout as we don't know about which // kind of iframe will be loaded. $this->spin( - function($context) use ($name){ + function ($context) use ($name) { $iframe = $context->find('iframe', $name); if ($iframe->hasAttribute('name')) { $iframename = $iframe->getAttribute('name'); @@ -274,7 +268,7 @@ class behat_general extends behat_base { throw new DriverException('Closing windows steps require javascript'); } $names = $this->getSession()->getWindowNames(); - for ($index = 1; $index < count($names); $index ++) { + for ($index = 1; $index < count($names); $index++) { $this->getSession()->switchToWindow($names[$index]); $this->execute_script("window.open('', '_self').close();"); } @@ -543,7 +537,9 @@ class behat_general extends behat_base { } /** - * Drags and drops the specified element to the specified container. This step does not work in all the browsers, consider it experimental. + * Drag and drops the specified element to the specified container. + * + * Note: This step does not work in all the browsers, consider it experimental. * * The steps definitions calling this step as part of them should * manage the wait times by themselves as the times and when the @@ -710,7 +706,7 @@ class behat_general extends behat_base { // should also ensure that the element is visible. Using microsleep as this // is a repeated step and global performance is important. $this->spin( - function($context, $args) { + function ($context, $args) { foreach ($args['nodes'] as $node) { if ($node->isVisible()) { @@ -719,18 +715,22 @@ class behat_general extends behat_base { } // If non of the nodes is visible we loop again. - throw new ExpectationException('"' . $args['text'] . '" text was found but was not visible', $context->getSession()); + throw new ExpectationException( + sprintf('"%s" text was found but was not visible', $args['text']), + $context->getSession(), + ); }, - array('nodes' => $nodes, 'text' => $text), + ['nodes' => $nodes, 'text' => $text], false, false, true ); - } /** - * Checks, that page doesn't contain specified text. When running Javascript tests it also considers that texts may be hidden. + * Ensure that page doesn't contain specified text. + * + * Note: When running Javascript tests it also considers that texts may be hidden. * * @Then /^I should not see "(?P(?:[^"]|\\")*)"$/ * @throws ExpectationException @@ -762,15 +762,17 @@ class behat_general extends behat_base { // If the element is there we should be sure that it is not visible. $this->spin( - function($context, $args) { + function ($context, $args) { foreach ($args['nodes'] as $node) { // If element is removed from dom, then just exit. try { // If element is visible then throw exception, so we keep spinning. if ($node->isVisible()) { - throw new ExpectationException('"' . $args['text'] . '" text was found in the page', - $context->getSession()); + throw new ExpectationException( + '"' . $args['text'] . '" text was found in the page', + $context->getSession() + ); } } catch (NoSuchElementException $e) { // Do nothing just return, as element is no more on page. @@ -784,7 +786,7 @@ class behat_general extends behat_base { // If non of the found nodes is visible we consider that the text is not visible. return true; }, - array('nodes' => $nodes, 'text' => $text), + ['nodes' => $nodes, 'text' => $text], behat_base::get_reduced_timeout(), false, true @@ -792,7 +794,9 @@ class behat_general extends behat_base { } /** - * Checks, that the specified element contains the specified text. When running Javascript tests it also considers that texts may be hidden. + * Ensure that the specified element contains the specified text. + * + * Note: When running Javascript tests it also considers that texts may be hidden. * * @Then /^I should see "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" "(?P[^"]*)"$/ * @throws ElementNotFoundException @@ -816,7 +820,10 @@ class behat_general extends behat_base { try { $nodes = $this->find_all('xpath', $xpath, false, $container); } catch (ElementNotFoundException $e) { - throw new ExpectationException('"' . $text . '" text was not found in the "' . $element . '" element', $this->getSession()); + throw new ExpectationException( + sprintf('"%s" text was not found in the "%s" element', $text, $element), + $this->getSession(), + ); } // If we are not running javascript we have enough with the @@ -828,17 +835,19 @@ class behat_general extends behat_base { // We also check the element visibility when running JS tests. Using microsleep as this // is a repeated step and global performance is important. $this->spin( - function($context, $args) { - + function ($context, $args) { foreach ($args['nodes'] as $node) { if ($node->isVisible()) { return true; } } - throw new ExpectationException('"' . $args['text'] . '" text was found in the "' . $args['element'] . '" element but was not visible', $context->getSession()); + throw new ExpectationException( + sprintf('"%s" text was found in the "%s" element but was not visible', $args['text'], $args['element']), + $context->getSession(), + ); }, - array('nodes' => $nodes, 'text' => $text, 'element' => $element), + ['nodes' => $nodes, 'text' => $text, 'element' => $element], false, false, true @@ -846,7 +855,9 @@ class behat_general extends behat_base { } /** - * Checks, that the specified element does not contain the specified text. When running Javascript tests it also considers that texts may be hidden. + * Ensure that the specified element does not contain the specified text. + * + * Note: When running Javascript tests it also considers that texts may be hidden. * * @Then /^I should not see "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" "(?P[^"]*)"$/ * @throws ElementNotFoundException @@ -883,18 +894,21 @@ class behat_general extends behat_base { // We need to ensure all the found nodes are hidden. $this->spin( - function($context, $args) { + function ($context, $args) { foreach ($args['nodes'] as $node) { if ($node->isVisible()) { - throw new ExpectationException('"' . $args['text'] . '" text was found in the "' . $args['element'] . '" element', $context->getSession()); + throw new ExpectationException( + sprintf('"%s" text was found in "%s" element', $args['text'], $args['element']), + $context->getSession(), + ); } } // If all the found nodes are hidden we are happy. return true; }, - array('nodes' => $nodes, 'text' => $text, 'element' => $element), + ['nodes' => $nodes, 'text' => $text, 'element' => $element], behat_base::get_reduced_timeout(), false, true @@ -1016,7 +1030,6 @@ class behat_general extends behat_base { EOF; $ok = $this->evaluate_script($js); } else { - // Using following xpath axe to find it. $xpath = "{$prexpath}/following::*[contains(., {$postxpath})]"; $ok = $this->getSession()->getDriver()->find($xpath); @@ -1256,8 +1269,10 @@ EOF; // Run all tasks which have a scheduled runtime of before now. $timenow = time(); - while (!\core\task\manager::static_caches_cleared_since($timenow) && - $task = \core\task\manager::get_next_adhoc_task($timenow)) { + while ( + !\core\task\manager::static_caches_cleared_since($timenow) && + $task = \core\task\manager::get_next_adhoc_task($timenow) + ) { // Clean the output buffer between tasks. ob_clean(); @@ -1412,12 +1427,16 @@ EOF; $containernode = $this->get_selected_node($selectortype, $element); $value = $containernode->getAttribute($attribute); if ($value == null) { - throw new ExpectationException('The attribute "' . $attribute. '" does not exist', - $this->getSession()); + throw new ExpectationException( + 'The attribute "' . $attribute . '" does not exist', + $this->getSession() + ); } else if (strpos($value, $text) === false) { - throw new ExpectationException('The attribute "' . $attribute . + throw new ExpectationException( + 'The attribute "' . $attribute . '" does not contain "' . $text . '" (actual value: "' . $value . '")', - $this->getSession()); + $this->getSession() + ); } } @@ -1436,12 +1455,16 @@ EOF; $containernode = $this->get_selected_node($selectortype, $element); $value = $containernode->getAttribute($attribute); if ($value == null) { - throw new ExpectationException('The attribute "' . $attribute. '" does not exist', - $this->getSession()); + throw new ExpectationException( + 'The attribute "' . $attribute . '" does not exist', + $this->getSession() + ); } else if (strpos($value, $text) !== false) { - throw new ExpectationException('The attribute "' . $attribute . + throw new ExpectationException( + 'The attribute "' . $attribute . '" contains "' . $text . '" (value: "' . $value . '")', - $this->getSession()); + $this->getSession() + ); } } @@ -1477,7 +1500,12 @@ EOF; $coumnnode = $this->getSession()->getDriver()->find($columnvaluexpath); if (empty($coumnnode)) { $locatorexceptionmsg = $value . '" in "' . $row . '" row with column "' . $column; - throw new ElementNotFoundException($this->getSession(), "\n$columnvaluexpath\n\n".'Column value', null, $locatorexceptionmsg); + throw new ElementNotFoundException( + $this->getSession(), + "\n$columnvaluexpath\n\n" . 'Column value', + null, + $locatorexceptionmsg, + ); } } @@ -1536,13 +1564,17 @@ EOF; if (strpos($column, '/') !== false) { // We are not able to match headers consisting of several links, such as "First name / Last name". // Instead we can match "First name" or "Last name" or "-1-" (column number). - throw new Exception("Column matching locator \"$column\" not found. ". - "If the column header contains multiple links, specify only one of the link texts. ". + throw new Exception("Column matching locator \"$column\" not found. " . + "If the column header contains multiple links, specify only one of the link texts. " . "Otherwise, use the column number as the locator"); } $columnexceptionmsg = $column . '" in table "' . $table . '"'; - throw new ElementNotFoundException($this->getSession(), "\n$columnheaderxpath\n\n".'Column', - null, $columnexceptionmsg); + throw new ElementNotFoundException( + $this->getSession(), + "\n$columnheaderxpath\n\n" . 'Column', + null, + $columnexceptionmsg + ); } // Following conditions were considered before finding column count. // 1. Table header can be in thead/tr/th or tbody/tr/td[1]. @@ -1574,7 +1606,7 @@ EOF; $rownode = $this->getSession()->getDriver()->find($rowxpath); if (empty($rownode)) { $rowlocator = array_map(fn($k) => "{$k} => {$cells[$k]}", array_keys($cells)); - throw new ElementNotFoundException($this->getSession(), "\n$rowxpath\n\n".'Table row', null, join(', ', $rowlocator)); + throw new ElementNotFoundException($this->getSession(), "\n$rowxpath\n\n" . 'Table row', null, join(', ', $rowlocator)); } } @@ -1594,8 +1626,7 @@ EOF; } $rowlocator = array_map(fn($k) => "{$k} => {$cells[$k]}", array_keys($cells)); throw new ExpectationException('Table row "' . join(', ', $rowlocator) . - '" is present in the table "' . $table . '"', $this->getSession() - ); + '" is present in the table "' . $table . '"', $this->getSession()); } /** @@ -1687,17 +1718,21 @@ EOF; // Get the href and check it. $url = $linknode->getAttribute('href'); if (!$url) { - throw new ExpectationException('Download link does not have href attribute', - $this->getSession()); + throw new ExpectationException( + 'Download link does not have href attribute', + $this->getSession() + ); } if (!preg_match('~^https?://~', $url)) { - throw new ExpectationException('Download link not an absolute URL: ' . $url, - $this->getSession()); + throw new ExpectationException( + 'Download link not an absolute URL: ' . $url, + $this->getSession() + ); } // Download the URL and check the size. $session = $this->getSession()->getCookie('MoodleSession'); - return download_file_content($url, array('Cookie' => 'MoodleSession=' . $session)); + return download_file_content($url, ['Cookie' => 'MoodleSession=' . $session]); } /** @@ -1718,11 +1753,11 @@ EOF; // It will stop spinning once file is downloaded or time out. $result = $this->spin( - function($context, $args) { + function ($context, $args) { $link = $args['link']; return $this->download_file_from_link($link); }, - array('link' => $link), + ['link' => $link], behat_base::get_extended_timeout(), $exception ); @@ -1753,7 +1788,11 @@ EOF; * @param number $maxexpectedsize the maximum expected file size in bytes. * @throws ExpectationException */ - public function following_should_download_between_and_bytes($link, $minexpectedsize, $maxexpectedsize) { + public function following_should_download_between_and_bytes( + $link, + $minexpectedsize, + $maxexpectedsize, + ) { // If the minimum is greater than the maximum then swap the values. if ((int)$minexpectedsize > (int)$maxexpectedsize) { [$minexpectedsize, $maxexpectedsize] = [$maxexpectedsize, $minexpectedsize]; @@ -1763,12 +1802,12 @@ EOF; // It will stop spinning once file is downloaded or time out. $result = $this->spin( - function($context, $args) { + function ($context, $args) { $link = $args['link']; return $this->download_file_from_link($link); }, - array('link' => $link), + ['link' => $link], behat_base::get_extended_timeout(), $exception ); @@ -1798,11 +1837,13 @@ EOF; $containernode = $this->get_selected_node($selectortype, $element); $url = $containernode->getAttribute('src'); if ($url == null) { - throw new ExpectationException('Element does not have src attribute', - $this->getSession()); + throw new ExpectationException( + 'Element does not have src attribute', + $this->getSession() + ); } $session = $this->getSession()->getCookie('MoodleSession'); - $content = download_file_content($url, array('Cookie' => 'MoodleSession=' . $session)); + $content = download_file_content($url, ['Cookie' => 'MoodleSession=' . $session]); // Get the content of the fixture file. // Replace 'admin/' if it is in start of path with $CFG->admin . @@ -1838,7 +1879,9 @@ EOF; // If we find this node at this point we are already watching for a reload and the behat steps // are out of order. We will treat this as an error - really it needs to be fixed as it indicates a problem. throw new ExpectationException( - 'Page load expectation error: page reloads are already been watched for.', $session); + 'Page load expectation error: page reloads are already been watched for.', + $session + ); } $this->pageloaddetectionrunning = true; @@ -1863,7 +1906,9 @@ EOF; // Make sure page load tracking was started. if (!$this->pageloaddetectionrunning) { throw new ExpectationException( - 'Page load expectation error: page load tracking was not started.', $session); + 'Page load expectation error: page load tracking was not started.', + $session + ); } // As the node is inserted by code above it is either there or not, and we do not need spin and it is safe @@ -1871,7 +1916,9 @@ EOF; if ($session->getPage()->find('xpath', $this->get_page_load_xpath())) { // We don't want to find this node, if we do we have an error. throw new ExpectationException( - 'Page load expectation error: a new page has not been loaded when it should have been.', $session); + 'Page load expectation error: a new page has not been loaded when it should have been.', + $session + ); } // Cancel the tracking of pageloaddetectionrunning. @@ -1890,7 +1937,9 @@ EOF; // Make sure page load tracking was started. if (!$this->pageloaddetectionrunning) { throw new ExpectationException( - 'Page load expectation error: page load tracking was not started.', $session); + 'Page load expectation error: page load tracking was not started.', + $session + ); } // We use our API here as we can use the exception handling provided by it. @@ -1958,7 +2007,7 @@ EOF; public function i_type(string $keys): void { // Certain keys, such as the newline character, must be converted to the appropriate character code. // Without this, keys will behave differently depending on the browser. - $keylist = array_map(function($key): string { + $keylist = array_map(function ($key): string { switch ($key) { case "\n": return behat_keys::ENTER; @@ -2117,14 +2166,16 @@ EOF; // Gets the node based on the requested selector type and locator. $node = $this->get_selected_node($selectortype, $element); $modifier = null; - $validmodifiers = array('ctrl', 'alt', 'shift', 'meta'); + $validmodifiers = ['ctrl', 'alt', 'shift', 'meta']; $char = $key; if (strpos($key, '-')) { [$modifier, $char] = preg_split('/-/', $key, 2); $modifier = strtolower($modifier); if (!in_array($modifier, $validmodifiers)) { - throw new ExpectationException(sprintf('Unknown key modifier: %s.', $modifier), - $this->getSession()); + throw new ExpectationException( + sprintf('Unknown key modifier: %s.', $modifier), + $this->getSession() + ); } } if (is_numeric($char)) { @@ -2189,7 +2240,8 @@ EOF; $path = core_component::get_component_directory($plugin); if (!is_readable($path . '/version.php')) { throw new \Moodle\BehatExtension\Exception\SkippedException( - 'Skipping this scenario because the ' . $plugin . ' is not installed.'); + 'Skipping this scenario because the ' . $plugin . ' is not installed.' + ); } } @@ -2288,7 +2340,8 @@ EOF; /** * Checks, that the specified element contains the specified text a certain amount of times. - * When running Javascript tests it also considers that texts may be hidden. + * + * Note: When running Javascript tests it also considers that texts may be hidden. * * @Then /^I should see "(?P\d+)" occurrences of "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" "(?P[^"]*)"$/ * @throws ElementNotFoundException @@ -2299,7 +2352,6 @@ EOF; * @param string $selectortype The type of element where we are looking in. */ public function i_should_see_occurrences_of_in_element($elementscount, $text, $element, $selectortype) { - // Getting the container where the text should be found. $container = $this->get_selected_node($selectortype, $element); @@ -2312,20 +2364,23 @@ EOF; $nodes = $this->find_all('xpath', $xpath, false, $container); if ($this->running_javascript()) { - $nodes = array_filter($nodes, function($node) { + $nodes = array_filter($nodes, function ($node) { return $node->isVisible(); }); } if ($elementscount != count($nodes)) { - throw new ExpectationException('Found '.count($nodes).' elements in column. Expected '.$elementscount, - $this->getSession()); + throw new ExpectationException( + 'Found ' . count($nodes) . ' elements in column. Expected ' . $elementscount, + $this->getSession() + ); } } /** * Checks, that the specified element contains the specified node type a certain amount of times. - * When running Javascript tests it also considers that texts may be hidden. + * + * Note: When running Javascript tests it also considers that texts may be hidden. * * @Then /^I should see "(?P\d+)" node occurrences of type "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" "(?P[^"]*)"$/ * @throws ElementNotFoundException @@ -2335,8 +2390,12 @@ EOF; * @param string $element Element we look in. * @param string $selectortype The type of element where we are looking in. */ - public function i_should_see_node_occurrences_of_type_in_element(int $elementscount, string $nodetype, string $element, string $selectortype) { - + public function i_should_see_node_occurrences_of_type_in_element( + int $elementscount, + string $nodetype, + string $element, + string $selectortype, + ) { // Getting the container where the text should be found. $container = $this->get_selected_node($selectortype, $element); @@ -2345,14 +2404,16 @@ EOF; $nodes = $this->find_all('xpath', $xpath, false, $container); if ($this->running_javascript()) { - $nodes = array_filter($nodes, function($node) { + $nodes = array_filter($nodes, function ($node) { return $node->isVisible(); }); } if ($elementscount != count($nodes)) { - throw new ExpectationException('Found '.count($nodes).' elements in column. Expected '.$elementscount, - $this->getSession()); + throw new ExpectationException( + 'Found ' . count($nodes) . ' elements in column. Expected ' . $elementscount, + $this->getSession() + ); } } @@ -2398,8 +2459,10 @@ EOF; */ public function i_click_on_the_dynamic_tab(string $tabname): void { $xpath = "//*[@id='dynamictabs-tabs'][descendant::a[contains(text(), '" . $this->escape($tabname) . "')]]"; - $this->execute([self::class, 'i_click_on_in_the'], - [$tabname, 'link', $xpath, 'xpath_element']); + $this->execute( + [self::class, 'i_click_on_in_the'], + [$tabname, 'link', $xpath, 'xpath_element'] + ); } /** @@ -2555,7 +2618,6 @@ EOF; } else { throw new \Behat\Mink\Exception\ExpectationException('Invalid state for switch: ' . $state, $this->getSession()); } - } /** @@ -2619,8 +2681,10 @@ EOF; * @param string $comboboxname The name (label) of the search combo box element. (e.g. "Search users", "Search groups"). */ public function i_confirm_in_search_combobox_exists(string $itemname, string $comboboxname): void { - $this->execute([self::class, 'assert_element_contains_text'], - [$itemname, $this->get_combobox_dropdown_node($comboboxname, $itemname, false), "NodeElement"]); + $this->execute( + [self::class, 'assert_element_contains_text'], + [$itemname, $this->get_combobox_dropdown_node($comboboxname, $itemname, false), "NodeElement"] + ); } /** @@ -2637,8 +2701,10 @@ EOF; * @param string $comboboxname The name (label) of the search combo box element. (e.g. "Search users", "Search groups"). */ public function i_confirm_in_search_combobox_does_not_exist(string $itemname, string $comboboxname): void { - $this->execute([self::class, 'assert_element_not_contains_text'], - [$itemname, $this->get_combobox_dropdown_node($comboboxname, $itemname, false), "NodeElement"]); + $this->execute( + [self::class, 'assert_element_not_contains_text'], + [$itemname, $this->get_combobox_dropdown_node($comboboxname, $itemname, false), "NodeElement"] + ); } /**