Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
moodle
moodle
Commits
647b675e
Commit
647b675e
authored
Jul 10, 2020
by
Jake Dallimore
Browse files
Merge branch 'MDL-69232-37' of
git://github.com/andrewnicols/moodle
into MOODLE_37_STABLE
parents
87f67ecc
eec91baf
Changes
1
Hide whitespace changes
Inline
Side-by-side
lib/tests/behat/behat_hooks.php
View file @
647b675e
...
...
@@ -68,6 +68,9 @@ class behat_hooks extends behat_base {
*/
protected
static
$initprocessesfinished
=
false
;
/** @var bool Whether the first javascript scenario has been seen yet */
protected
static
$firstjavascriptscenarioseen
=
false
;
/**
* @var bool Scenario running
*/
...
...
@@ -110,39 +113,22 @@ class behat_hooks extends behat_base {
protected
static
$scenariotags
;
/**
* Hook to capture BeforeSuite event so as to give access to moodle codebase.
* This will try and catch any exception and exists if anything fails.
* Gives access to moodle codebase, ensures all is ready and sets up the test lock.
*
* Includes config.php to use moodle codebase with $CFG->behat_* instead of $CFG->prefix and $CFG->dataroot, called
* once per suite.
*
* @param BeforeSuiteScope $scope scope passed by event fired before suite.
* @BeforeSuite
* @param BeforeSuiteScope $scope scope passed by event fired before suite.
*/
public
static
function
before_suite_hook
(
BeforeSuiteScope
$scope
)
{
global
$CFG
;
// If behat has been initialised then no need to do this again.
if
(
self
::
$initprocessesfinished
)
{
if
(
!
self
::
is_first_scenario
()
)
{
return
;
}
try
{
self
::
before_suite
(
$scope
);
}
catch
(
behat_stop_exception
$e
)
{
echo
$e
->
getMessage
()
.
PHP_EOL
;
exit
(
1
);
}
}
/**
* Gives access to moodle codebase, ensures all is ready and sets up the test lock.
*
* Includes config.php to use moodle codebase with $CFG->behat_*
* instead of $CFG->prefix and $CFG->dataroot, called once per suite.
*
* @param BeforeSuiteScope $scope scope passed by event fired before suite.
* @static
* @throws behat_stop_exception
*/
public
static
function
before_suite
(
BeforeSuiteScope
$scope
)
{
global
$CFG
;
// Defined only when the behat CLI command is running, the moodle init setup process will
// read this value and switch to $CFG->behat_dataroot and $CFG->behat_prefix instead of
// the normal site.
...
...
@@ -170,8 +156,7 @@ class behat_hooks extends behat_base {
// before each scenario (accidental user deletes) in the BeforeScenario hook.
if
(
!
behat_util
::
is_test_mode_enabled
())
{
throw
new
behat_stop_exception
(
'Behat only can run if test mode is enabled. More info in '
.
behat_command
::
DOCS_URL
);
self
::
log_and_stop
(
'Behat only can run if test mode is enabled. More info in '
.
behat_command
::
DOCS_URL
);
}
// Reset all data, before checking for check_server_status.
...
...
@@ -179,20 +164,28 @@ class behat_hooks extends behat_base {
behat_util
::
clean_tables_updated_by_scenario_list
();
behat_util
::
reset_all_data
();
// Check if server is running and using same version for cli and apache.
// Check if
the web
server is running and using same version for cli and apache.
behat_util
::
check_server_status
();
// Prevents using outdated data, upgrade script would start and tests would fail.
if
(
!
behat_util
::
is_test_data_updated
())
{
$commandpath
=
'php admin/tool/behat/cli/init.php'
;
throw
new
behat_stop_exception
(
"Your behat test site is outdated, please run
\n\n
"
.
$commandpath
.
"
\n\n
from your moodle dirroot to drop and install the behat test site again."
);
$message
=
<<<EOF
Your behat test site is outdated, please run the following command from your Moodle dirroot to drop, and reinstall the Behat test site.
{$comandpath}
EOF;
self
::
log_and_stop
(
$message
);
}
// Avoid parallel tests execution, it continues when the previous lock is released.
test_lock
::
acquire
(
'behat'
);
if
(
!
empty
(
$CFG
->
behat_faildump_path
)
&&
!
is_writable
(
$CFG
->
behat_faildump_path
))
{
throw
new
behat_stop_exception
(
'You set $CFG->behat_faildump_path to a non-writable directory'
);
self
::
log_and_stop
(
"The
\$
CFG->behat_faildump_path value is set to a non-writable directory (
{
$CFG
->
behat_faildump_path
}
)."
);
}
// Handle interrupts on PHP7.
...
...
@@ -204,6 +197,25 @@ class behat_hooks extends behat_base {
}
}
/**
* Run final tests before running the suite.
*
* @BeforeSuite
* @param BeforeSuiteScope $scope scope passed by event fired before suite.
*/
public
static
function
before_suite_final_checks
(
BeforeSuiteScope
$scope
)
{
$happy
=
defined
(
'BEHAT_TEST'
);
$happy
=
$happy
&&
defined
(
'BEHAT_SITE_RUNNING'
);
$happy
=
$happy
&&
php_sapi_name
()
==
'cli'
;
$happy
=
$happy
&&
behat_util
::
is_test_mode_enabled
();
$happy
=
$happy
&&
behat_util
::
is_test_site
();
if
(
!
$happy
)
{
error_log
(
'Behat only can modify the test database and the test dataroot!'
);
exit
(
1
);
}
}
/**
* Gives access to moodle codebase, to keep track of feature start time.
*
...
...
@@ -260,53 +272,108 @@ class behat_hooks extends behat_base {
}
/**
* Hook to capture before scenario event to get scope.
* Helper function to restart the Mink session.
*/
protected
function
restart_session
():
void
{
$session
=
$this
->
getSession
();
if
(
$session
->
isStarted
())
{
$session
->
restart
();
}
else
{
$session
->
start
();
}
if
(
$this
->
running_javascript
()
&&
$this
->
getSession
()
->
getDriver
()
->
getWebDriverSessionId
()
===
'session'
)
{
throw
new
DriverException
(
'Unable to create a valid session'
);
}
}
/**
* Restart the session before each non-javascript scenario.
*
* @BeforeScenario @~javascript
* @param BeforeScenarioScope $scope scope passed by event fired before scenario.
* @BeforeScenario
*/
public
function
before_scenario
_hook
(
BeforeScenarioScope
$scope
)
{
try
{
$this
->
b
efore
_s
cenario
(
$scope
);
}
catch
(
behat_stop_exception
$e
)
{
echo
$e
->
getMessage
()
.
PHP_EOL
;
exit
(
1
)
;
public
function
before_
goutte_
scenario
s
(
BeforeScenarioScope
$scope
)
{
if
(
$this
->
running_javascript
())
{
// A bug in the B
efore
S
cenario
filtering prevents the @~javascript filter on this hook from working
// properly.
// See https://github.com/Behat/Behat/issues/1235 for further information.
return
;
}
$this
->
restart_session
();
}
/**
*
Resets the test environment
.
*
Start the session before the first javascript scenario
.
*
* This is treated slightly differently to try to capture when Selenium is not running at all.
*
* @BeforeScenario @javascript
* @param BeforeScenarioScope $scope scope passed by event fired before scenario.
* @throws behat_stop_exception If here we are not using the test database it should be because of a coding error
*/
public
function
before_scenario
(
BeforeScenarioScope
$scope
)
{
global
$DB
,
$CFG
;
// As many checks as we can.
if
(
!
defined
(
'BEHAT_TEST'
)
||
!
defined
(
'BEHAT_SITE_RUNNING'
)
||
php_sapi_name
()
!=
'cli'
||
!
behat_util
::
is_test_mode_enabled
()
||
!
behat_util
::
is_test_site
())
{
throw
new
behat_stop_exception
(
'Behat only can modify the test database and the test dataroot!'
);
public
function
before_first_scenario_start_session
(
BeforeScenarioScope
$scope
)
{
if
(
!
self
::
is_first_javascript_scenario
())
{
// The first Scenario has started.
// The `before_subsequent_scenario_start_session` function will restart the session instead.
return
;
}
self
::
$firstjavascriptscenarioseen
=
true
;
$docsurl
=
behat_command
::
DOCS_URL
;
$driverexceptionmsg
=
<<<EOF
The Selenium or WebDriver server is not running. You must start it to run tests that involve Javascript.
See {$docsurl} for more information.
The following debugging information is available:
EOF;
$moreinfo
=
'More info in '
.
behat_command
::
DOCS_URL
;
$driverexceptionmsg
=
'Selenium server is not running, you need to start it to run tests that involve Javascript. '
.
$moreinfo
;
try
{
$session
=
$this
->
getSession
();
}
catch
(
CurlExec
$e
)
{
// Exception thrown by WebDriver, so only @javascript tests will be caugth; in
// behat_util::check_server_status() we already checked that the server is running.
throw
new
behat_stop_exception
(
$driverexceptionmsg
);
}
catch
(
DriverException
$e
)
{
throw
new
behat_stop_exception
(
$driverexceptionmsg
);
$this
->
restart_session
();
}
catch
(
CurlExec
|
DriverException
$e
)
{
// The CurlExec Exception is thrown by WebDriver.
self
::
log_and_stop
(
$driverexceptionmsg
.
'. '
.
$e
->
getMessage
()
.
"
\n\n
"
.
format_backtrace
(
$e
->
getTrace
(),
true
)
);
}
catch
(
UnknownError
$e
)
{
// Generic 'I have no idea' Selenium error. Custom exception to provide more feedback about possible solutions.
throw
new
behat_stop_exception
(
$e
->
getMessage
());
self
::
log_and_stop
(
$e
->
getMessage
()
.
"
\n\n
"
.
format_backtrace
(
$e
->
getTrace
(),
true
)
);
}
}
/**
* Start the session before each javascript scenario.
*
* Note: Before the first scenario the @see before_first_scenario_start_session() function is used instead.
*
* @BeforeScenario @javascript
* @param BeforeScenarioScope $scope scope passed by event fired before scenario.
*/
public
function
before_subsequent_scenario_start_session
(
BeforeScenarioScope
$scope
)
{
if
(
self
::
is_first_javascript_scenario
())
{
// The initial init has not yet finished.
// The `before_first_scenario_start_session` function will have started the session instead.
return
;
}
$this
->
restart_session
();
}
/**
* Resets the test environment.
*
* @BeforeScenario
* @param BeforeScenarioScope $scope scope passed by event fired before scenario.
*/
public
function
before_scenario_hook
(
BeforeScenarioScope
$scope
)
{
global
$DB
;
$suitename
=
$scope
->
getSuite
()
->
getName
();
// Register behat selectors for theme, if suite is changed. We do it for every suite change.
...
...
@@ -340,9 +407,6 @@ class behat_hooks extends behat_base {
}
// Reset mink session between the scenarios.
$session
->
reset
();
// Reset $SESSION.
\
core\session\manager
::
init_empty_session
();
...
...
@@ -695,6 +759,15 @@ class behat_hooks extends behat_base {
return
!
(
self
::
$initprocessesfinished
);
}
/**
* Returns whether the first scenario of the suite is running
*
* @return bool
*/
protected
static
function
is_first_javascript_scenario
():
bool
{
return
!
self
::
$firstjavascriptscenarioseen
;
}
/**
* Register a set of component selectors.
*
...
...
@@ -734,20 +807,19 @@ class behat_hooks extends behat_base {
* @param BeforeStepScope $scope
* @BeforeStep
*/
public
function
first_step_setup_complete
(
BeforeStepScope
$scope
)
{
public
function
first_step_setup_complete
(
BeforeStepScope
$scope
)
:
void
{
self
::
$initprocessesfinished
=
true
;
}
}
/**
* Log a notification, and then exit.
*
* @param string $message The content to dispaly
*/
protected
static
function
log_and_stop
(
string
$message
):
void
{
error_log
(
$message
);
exit
(
1
);
}
/**
* Behat stop exception
*
* This exception is thrown from before suite or scenario if any setup problem found.
*
* @package core_test
* @copyright 2016 Rajesh Taneja <rajesh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class
behat_stop_exception
extends
\
Exception
{
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment