2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
22 * @copyright 2012 David MonllaĆ³
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
28 require_once(__DIR__
. '/../lib.php');
31 * Behat command related utils
35 * @copyright 2013 David MonllaĆ³
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 const DOCS_URL
= 'http://docs.moodle.org/dev/Acceptance_testing';
46 * Ensures the behat dir exists in moodledata
47 * @return string Full path
49 public static function get_behat_dir() {
52 $behatdir = $CFG->behat_dataroot
. '/behat';
54 if (!is_dir($behatdir)) {
55 if (!mkdir($behatdir, $CFG->directorypermissions
, true)) {
56 behat_error(BEHAT_EXITCODE_PERMISSIONS
, 'Directory ' . $behatdir . ' can not be created');
60 if (!is_writable($behatdir)) {
61 behat_error(BEHAT_EXITCODE_PERMISSIONS
, 'Directory ' . $behatdir . ' is not writable');
68 * Returns the executable path
70 * Allows returning a customized command for cygwin when the
71 * command is just displayed, when using exec(), system() and
72 * friends we stay with DIRECTORY_SEPARATOR as they use the
73 * normal cmd.exe (in Windows).
75 * @param bool $custombyterm If the provided command should depend on the terminal where it runs
78 public final static function get_behat_command($custombyterm = false) {
80 $separator = DIRECTORY_SEPARATOR
;
83 // Cygwin uses linux-style directory separators.
84 if ($custombyterm && testing_is_cygwin()) {
87 // MinGW can not execute .bat scripts.
88 if (!testing_is_mingw()) {
92 return 'vendor' . $separator . 'bin' . $separator . $exec;
96 * Runs behat command with provided options
98 * Execution continues when the process finishes
100 * @param string $options Defaults to '' so tests would be executed
101 * @return array CLI command outputs [0] => string, [1] => integer
103 public final static function run($options = '') {
106 $currentcwd = getcwd();
107 chdir($CFG->dirroot
);
108 exec(self
::get_behat_command() . ' ' . $options, $output, $code);
111 return array($output, $code);
115 * Checks if behat is set up and working
117 * Notifies failures both from CLI and web interface.
119 * It checks behat dependencies have been installed and runs
120 * the behat help command to ensure it works as expected
122 * @return int Error code or 0 if all ok
124 public static function behat_setup_problem() {
128 if (!self
::are_behat_dependencies_installed()) {
130 // Returning composer error code to avoid conflicts with behat and moodle error codes.
131 self
::output_msg(get_string('errorcomposer', 'tool_behat'));
132 return BEHAT_EXITCODE_COMPOSER
;
135 // Behat test command.
136 list($output, $code) = self
::run(' --help');
140 // Returning composer error code to avoid conflicts with behat and moodle error codes.
141 self
::output_msg(get_string('errorbehatcommand', 'tool_behat', self
::get_behat_command()));
142 return BEHAT_EXITCODE_COMPOSER
;
146 if (empty($CFG->behat_dataroot
) ||
empty($CFG->behat_prefix
) ||
empty($CFG->behat_wwwroot
)) {
147 self
::output_msg(get_string('errorsetconfig', 'tool_behat'));
148 return BEHAT_EXITCODE_CONFIG
;
152 // Not repeated values.
153 // We only need to check this when the behat site is not running as
154 // at this point, when it is running, all $CFG->behat_* vars have
155 // already been copied to $CFG->dataroot, $CFG->prefix and $CFG->wwwroot.
156 if (!defined('BEHAT_SITE_RUNNING') &&
157 ($CFG->behat_prefix
== $CFG->prefix ||
158 $CFG->behat_dataroot
== $CFG->dataroot ||
159 $CFG->behat_wwwroot
== $CFG->wwwroot ||
160 (!empty($CFG->phpunit_prefix
) && $CFG->phpunit_prefix
== $CFG->behat_prefix
) ||
161 (!empty($CFG->phpunit_dataroot
) && $CFG->phpunit_dataroot
== $CFG->behat_dataroot
)
163 self
::output_msg(get_string('erroruniqueconfig', 'tool_behat'));
164 return BEHAT_EXITCODE_CONFIG
;
167 // Checking behat dataroot existence otherwise echo about admin/tool/behat/cli/init.php.
168 if (!empty($CFG->behat_dataroot
)) {
169 $CFG->behat_dataroot
= realpath($CFG->behat_dataroot
);
171 if (empty($CFG->behat_dataroot
) ||
!is_dir($CFG->behat_dataroot
) ||
!is_writable($CFG->behat_dataroot
)) {
172 self
::output_msg(get_string('errordataroot', 'tool_behat'));
173 return BEHAT_EXITCODE_CONFIG
;
180 * Has the site installed composer with --dev option
183 public static function are_behat_dependencies_installed() {
184 if (!is_dir(__DIR__
. '/../../../vendor/behat')) {
193 * Used in CLI + web UI methods. Stops the
199 protected static function output_msg($msg) {
202 // If we are using the web interface we want pretty messages.
205 $renderer = $PAGE->get_renderer('tool_behat');
206 echo $renderer->render_error($msg);
208 // Stopping execution.
213 // We continue execution after this.
214 $clibehaterrorstr = "Ensure you set \$CFG->behat_* vars in config.php " .
215 "and you ran admin/tool/behat/cli/init.php.\n" .
216 "More info in " . self
::DOCS_URL
. "#Installation\n\n";
218 echo 'Error: ' . $msg . "\n\n" . $clibehaterrorstr;