MDL-86231 behat: Coding style fixes

This commit is contained in:
Andrew Nicols
2025-08-08 08:44:48 +08:00
parent f50da71a49
commit f3158b3fcf
2 changed files with 191 additions and 118 deletions
@@ -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);
+156 -90
View File
@@ -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<text_string>(?:[^"]|\\")*)"$/
* @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<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)"$/
* @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<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)"$/
* @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<elementscount_number>\d+)" occurrences of "(?P<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)"$/
* @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<elementscount_number>\d+)" node occurrences of type "(?P<node_type>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)"$/
* @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"]
);
}
/**