Merge branch 'MDL-66675-35' of git://github.com/andrewnicols/moodle into MOODLE_35_STABLE

This commit is contained in:
Eloy Lafuente (stronk7)
2019-09-25 20:06:38 +02:00
5 changed files with 120 additions and 32 deletions
+4
View File
@@ -812,6 +812,10 @@ $CFG->admin = 'admin';
// Example:
// $CFG->behat_faildump_path = '/my/path/to/save/failure/dumps';
//
// You can make behat pause upon failure to help you diagnose and debug problems with your tests.
//
// $CFG->behat_pause_on_fail = true;
//
// You can specify db, selenium wd_host etc. for behat parallel run by setting following variable.
// Example:
// $CFG->behat_parallel_run = array (
+37
View File
@@ -31,6 +31,9 @@ require_once(__DIR__ . '/behat_command.php');
require_once(__DIR__ . '/behat_config_manager.php');
require_once(__DIR__ . '/../../filelib.php');
require_once(__DIR__ . '/../../clilib.php');
use Behat\Mink\Session;
/**
* Init/reset utilities for Behat database and dataroot
@@ -373,4 +376,38 @@ class behat_util extends testing_util {
// $CFG values from the old run. @see set_config.
initialise_cfg();
}
/**
* Pause execution immediately.
*
* @param Session $session
* @param string $message The message to show when pausing.
* This will be passed through cli_ansi_format so appropriate ANSI formatting and features are available.
*/
public static function pause(Session $session, string $message): void {
$posixexists = function_exists('posix_isatty');
// Make sure this step is only used with interactive terminal (if detected).
if ($posixexists && !@posix_isatty(STDOUT)) {
throw new ExpectationException('Break point should only be used with interactive terminal.', $session);
}
// Save the cursor position, ring the bell, and add a new line.
fwrite(STDOUT, cli_ansi_format("<cursor:save><bell><newline>"));
// Output the formatted message and reset colour back to normal.
$formattedmessage = cli_ansi_format("{$message}<colour:normal>");
fwrite(STDOUT, $formattedmessage);
// Wait for input.
fread(STDIN, 1024);
// Move the cursor back up to the previous position, then restore the original position stored earlier, and move
// it back down again.
fwrite(STDOUT, cli_ansi_format("<cursor:up><cursor:up><cursor:restore><cursor:down><cursor:down>"));
// Add any extra lines back if the provided message was spread over multiple lines.
$linecount = count(explode("\n", $formattedmessage));
fwrite(STDOUT, str_repeat(cli_ansi_format("<cursor:down>"), $linecount - 1));
}
}
+56
View File
@@ -227,3 +227,59 @@ function cli_logo($padding=2, $return=false) {
cli_write($logo);
}
}
/**
* Substitute cursor, colour, and bell placeholders in a CLI output to ANSI escape characters when ANSI is available.
*
* @param string $message
* @return string
*/
function cli_ansi_format(string $message): string {
global $CFG;
$replacements = [
"<newline>" => "\n",
"<bell>" => "\007",
// Cursor movement: https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html.
"<cursor:save>" => "\033[s",
"<cursor:restore>" => "\033[u",
"<cursor:up>" => "\033[1A",
"<cursor:down>" => "\033[1B",
"<cursor:forward>" => "\033[1C",
"<cursor:back>" => "\033[1D",
];
$colours = [
'normal' => '0;0',
'black' => '0;30',
'darkGray' => '1;30',
'blue' => '0;34',
'lightBlue' => '1;34',
'green' => '0;32',
'lightGreen' => '1;32',
'cyan' => '0;36',
'lightCyan' => '1;36',
'red' => '0;31',
'lightRed' => '1;31',
'purple' => '0;35',
'lightPurple' => '1;35',
'brown' => '0;33',
'yellow' => '1;33',
'lightYellow' => '0;93',
'lightGray' => '0;37',
'white' => '1;37',
];
foreach ($colours as $colour => $code) {
$replacements["<colour:{$colour}>"] = "\033[{$code}m";
}
// Windows don't support ANSI code by default, but does if ANSICON is available.
$isansicon = getenv('ANSICON');
if (($CFG->ostype === 'WINDOWS') && empty($isansicon)) {
return str_replace(array_keys($replacements), '', $message);
}
return str_replace(array_keys($replacements), array_values($replacements), $message);
}
+3 -21
View File
@@ -1595,27 +1595,9 @@ EOF;
*
* @Then /^(?:|I )pause(?:| scenario execution)$/
*/
public function i_pause_scenario_executon() {
global $CFG;
$posixexists = function_exists('posix_isatty');
// Make sure this step is only used with interactive terminal (if detected).
if ($posixexists && !@posix_isatty(STDOUT)) {
$session = $this->getSession();
throw new ExpectationException('Break point should only be used with interative terminal.', $session);
}
// Windows don't support ANSI code by default, but with ANSICON.
$isansicon = getenv('ANSICON');
if (($CFG->ostype === 'WINDOWS') && empty($isansicon)) {
fwrite(STDOUT, "Paused. Press Enter/Return to continue.");
fread(STDIN, 1024);
} else {
fwrite(STDOUT, "\033[s\n\033[0;93mPaused. Press \033[1;31mEnter/Return\033[0;93m to continue.\033[0m");
fread(STDIN, 1024);
fwrite(STDOUT, "\033[2A\033[u\033[2B");
}
public function i_pause_scenario_execution() {
$message = "<colour:lightYellow>Paused. Press <colour:lightRed>Enter/Return<colour:lightYellow> to continue.";
behat_util::pause($this->getSession(), $message);
}
/**
+20 -11
View File
@@ -466,11 +466,7 @@ class behat_hooks extends behat_base {
throw new coding_exception("Step '" . $scope->getStep()->getText() . "'' is undefined.");
}
// Save the page content if the step failed.
if (!empty($CFG->behat_faildump_path) &&
$scope->getTestResult()->getResultCode() === Behat\Testwork\Tester\Result\TestResult::FAILED) {
$this->take_contentdump($scope);
}
$isfailed = $scope->getTestResult()->getResultCode() === Behat\Testwork\Tester\Result\TestResult::FAILED;
// Abort any open transactions to prevent subsequent tests hanging.
// This does the same as abort_all_db_transactions(), but doesn't call error_log() as we don't
@@ -482,17 +478,30 @@ class behat_hooks extends behat_base {
}
}
if ($isfailed && !empty($CFG->behat_faildump_path)) {
// Save the page content (html).
$this->take_contentdump($scope);
if ($this->running_javascript()) {
// Save a screenshot.
$this->take_screenshot($scope);
}
}
if ($isfailed && !empty($CFG->behat_pause_on_fail)) {
$exception = $scope->getTestResult()->getException();
$message = "<colour:lightRed>Scenario failed. ";
$message .= "<colour:lightYellow>Paused for inspection. Press <colour:lightRed>Enter/Return<colour:lightYellow> to continue.<newline>";
$message .= "<colour:lightRed>Exception follows:<newline>";
$message .= trim($exception->getMessage());
behat_util::pause($this->getSession(), $message);
}
// Only run if JS.
if (!$this->running_javascript()) {
return;
}
// Save a screenshot if the step failed.
if (!empty($CFG->behat_faildump_path) &&
$scope->getTestResult()->getResultCode() === Behat\Testwork\Tester\Result\TestResult::FAILED) {
$this->take_screenshot($scope);
}
try {
$this->wait_for_pending_js();
self::$currentstepexception = null;