<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cschoeffel</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cschoeffel"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Cschoeffel"/>
	<updated>2026-04-18T19:01:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_PhpStorm&amp;diff=57830</id>
		<title>Setting up PhpStorm</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_PhpStorm&amp;diff=57830"/>
		<updated>2020-09-05T13:12:20Z</updated>

		<summary type="html">&lt;p&gt;Cschoeffel: /* Tips &amp;amp; Tricks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.jetbrains.com/phpstorm/ PhpStorm] is a commercial IDE, it is arguably the best IDE for PHP developers with features such as code completion, code inspection, phpunit support, Behat support, database editor, debugger, etc.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
===OS X===&lt;br /&gt;
&lt;br /&gt;
Do not install Java manually, download a PhpStorm package with bundled java instead.&lt;br /&gt;
&lt;br /&gt;
==General settings==&lt;br /&gt;
&lt;br /&gt;
* Disable missing @throws tag warning in &amp;quot;Preferences / Project Settings / Inspections / PHP / PHPDoc&amp;quot;&lt;br /&gt;
* Strip trailing whitespace from &amp;quot;Modified Lines&amp;quot; in &amp;quot;Preferences / IDE Settings / Editor/ General&amp;quot;&lt;br /&gt;
* Show line numbers in &amp;quot;Preferences / IDE Settings / Editor / Appearance&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Bug tracker integration==&lt;br /&gt;
&lt;br /&gt;
* Add tracker linking in &amp;quot;Preferences / Version control / Issue Navigation&amp;quot;&lt;br /&gt;
* Set Issue ID to &amp;quot;MDL-\d+&amp;quot; and Issue link to &amp;quot;https://tracker.moodle.org/browse/$0&amp;quot; or just click on &#039;add Jira pattern&#039; and paste &amp;quot;https://tracker.moodle.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Code formatting==&lt;br /&gt;
&lt;br /&gt;
* Setup coding style to use all rules from [[Coding style]] in &amp;quot;Preferences / Project Settings / Code Style / PHP&amp;quot; (or simply import from https://github.com/enovation/moodle-utils/blob/master/phpstorm-config/Moodle.xml) - this will allow you to use automatic code formatting and it does nice code formatting on copy/paste.&lt;br /&gt;
* Set line separator to &amp;quot;Unix and OS X (\n)&amp;quot; in &amp;quot;Preferences / Project Settings / Code Style / General&amp;quot;.&lt;br /&gt;
* Set right margin to 132 or 180 in &amp;quot;Preferences / Project Settings / Code Style / General&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Tips &amp;amp; Tricks==&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code php&amp;gt;/** @var admin_root $ADMIN */&amp;lt;/code&amp;gt;  to autofill $ADMIN-&amp;gt;...&lt;br /&gt;
* Remove SQL syntax inspection errors for Moodle tables surrounded by curly brackets (like: &amp;lt;code php&amp;gt;SELECT * FROM {user}&amp;lt;/code&amp;gt;)  by adding &amp;lt;code php&amp;gt;\{(\w+)\}&amp;lt;/code&amp;gt; to Tools &amp;gt; Databases &amp;gt; user parameters &lt;br /&gt;
(more info: https://blog.jetbrains.com/phpstorm/2014/11/database-language-injection-configuration/ , and a &amp;quot;feature request&amp;quot; to improve it: https://youtrack.jetbrains.com/issue/WI-4123 )&lt;br /&gt;
* You can deactivate warnings for specific exceptions (in particular the coding_exception, which is unlikely to be catched in your code) by going to Settings &amp;gt; PHP and add them to &#039;Unchecked Exceptions&#039; under the &#039;Analysis&#039; tab&lt;br /&gt;
&lt;br /&gt;
==Moodle code checker==&lt;br /&gt;
Follow the instructions in the [https://github.com/moodlehq/moodle-local_codechecker/blob/master/README.md#ide-integration README]&lt;br /&gt;
&lt;br /&gt;
==PHPUnit integration==&lt;br /&gt;
# Install [[PHPUnit]] via Composer &lt;br /&gt;
# Tell PHPStorm where is composer - go to &amp;quot;Preferences / PHP / Composer&amp;quot;, fill in &amp;quot;Path to PHP executable&amp;quot;, &amp;quot;Path to composer.phar&amp;quot;, &amp;quot;Path to composer.json&amp;quot; and make sure the option &amp;quot;Add packages as libraries&amp;quot; is enabled.&lt;br /&gt;
# Go to &amp;quot;Run / Edit configurations&amp;quot;&lt;br /&gt;
# Add PHPUnit configuration by clicking on &amp;quot;+&amp;quot;&lt;br /&gt;
# Click &amp;quot;Use alternative configuration file&amp;quot; and select your phpunit.xml file&lt;br /&gt;
# Go to &amp;quot;Run / Run ...&amp;quot; and select your new PHPUnit configuration to run&lt;br /&gt;
&lt;br /&gt;
==Database editor==&lt;br /&gt;
# Click on the &amp;quot;Database&amp;quot; tab to see the database window&lt;br /&gt;
# Click &amp;quot;+&amp;quot; in the top left and add &amp;quot;Database source&amp;quot; for your database&lt;br /&gt;
# Note: click on the link to download the necessary drivers directly from IDE&lt;br /&gt;
&lt;br /&gt;
==Useful plugins==&lt;br /&gt;
&lt;br /&gt;
# Php Inspections ​(EA Extended) - https://plugins.jetbrains.com/plugin/7622-php-inspections-ea-extended-/&lt;br /&gt;
# SonarLint - https://plugins.jetbrains.com/plugin/7973-sonarlint/&lt;br /&gt;
# Diff / Patch File Support - https://plugins.jetbrains.com/plugin/11957-diff--patch-file-support/&lt;br /&gt;
# Handlebars/Mustache - https://plugins.jetbrains.com/plugin/6884-handlebars-mustache/&lt;br /&gt;
# Markdown Navigator - https://plugins.jetbrains.com/plugin/7896-markdown-navigator/&lt;br /&gt;
# PHP composer.json support - https://plugins.jetbrains.com/plugin/7631-php-composer-json-support/&lt;br /&gt;
# PHP Advanced AutoComplete - https://plugins.jetbrains.com/plugin/7276-php-advanced-autocomplete/&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer tools|PhpStorm]]&lt;/div&gt;</summary>
		<author><name>Cschoeffel</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Form_API&amp;diff=57728</id>
		<title>Form API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Form_API&amp;diff=57728"/>
		<updated>2020-07-22T17:56:00Z</updated>

		<summary type="html">&lt;p&gt;Cschoeffel: /* Basic form elements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
Web Forms in moodle are created using forms API. Form API supports all html elements (checkbox, radio, textbox etc), with improved accessibility and security.&lt;br /&gt;
==Highlights==&lt;br /&gt;
# Tested and optimised for use on major screen-readers Dragon and JAWS. &lt;br /&gt;
# Tableless layout.&lt;br /&gt;
# Process form data securely, with required_param, optional_param and session key.&lt;br /&gt;
# Supports client-side validation&lt;br /&gt;
# Facility to add Moodle help buttons to forms. &lt;br /&gt;
# Support for file repository using [[File_API]]&lt;br /&gt;
# Support for many custom moodle specific and non-specific form elements.&lt;br /&gt;
# Addition for [https://docs.moodle.org/dev/lib/formslib.php_repeat_elements repeated elements].&lt;br /&gt;
# Addition for form elements in advance group&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
For creating a form in moodle, you have to create class extending moodleform class and override [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#definition.28.29 definition] for including form elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
//moodleform is defined in formslib.php&lt;br /&gt;
require_once(&amp;quot;$CFG-&amp;gt;libdir/formslib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
class simplehtml_form extends moodleform {&lt;br /&gt;
    //Add elements to form&lt;br /&gt;
    public function definition() {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
       &lt;br /&gt;
        $mform = $this-&amp;gt;_form; // Don&#039;t forget the underscore! &lt;br /&gt;
&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;email&#039;, get_string(&#039;email&#039;)); // Add elements to your form&lt;br /&gt;
        $mform-&amp;gt;setType(&#039;email&#039;, PARAM_NOTAGS);                   //Set type of element&lt;br /&gt;
        $mform-&amp;gt;setDefault(&#039;email&#039;, &#039;Please enter email&#039;);        //Default value&lt;br /&gt;
            ...&lt;br /&gt;
    }&lt;br /&gt;
    //Custom validation should be added here&lt;br /&gt;
    function validation($data, $files) {&lt;br /&gt;
        return array();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Then instantiate form (in this case simplehtml_form) on your page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
//include simplehtml_form.php&lt;br /&gt;
require_once(&#039;PATH_TO/simplehtml_form.php&#039;);&lt;br /&gt;
&lt;br /&gt;
//Instantiate simplehtml_form &lt;br /&gt;
$mform = new simplehtml_form();&lt;br /&gt;
&lt;br /&gt;
//Form processing and displaying is done here&lt;br /&gt;
if ($mform-&amp;gt;is_cancelled()) {&lt;br /&gt;
    //Handle form cancel operation, if cancel button is present on form&lt;br /&gt;
} else if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
  //In this case you process validated data. $mform-&amp;gt;get_data() returns data posted in form.&lt;br /&gt;
} else {&lt;br /&gt;
  // this branch is executed if the form is submitted but the data doesn&#039;t validate and the form should be redisplayed&lt;br /&gt;
  // or on the first display of the form.&lt;br /&gt;
&lt;br /&gt;
  //Set default data (if any)&lt;br /&gt;
  $mform-&amp;gt;set_data($toform);&lt;br /&gt;
  //displays the form&lt;br /&gt;
  $mform-&amp;gt;display();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wish to use the form within a block then you should consider using the render method, as demonstrated below:&lt;br /&gt;
&lt;br /&gt;
Note that the render method does the same as the display method, except returning the HTML rather than outputting it to the browser, as with above make sure you&#039;ve included the file which contains the class for your Moodle form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class block_yourblock extends block_base{&lt;br /&gt;
	public function init(){&lt;br /&gt;
		$this-&amp;gt;title = &#039;Your Block&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	public function get_content(){&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;content = new stdClass();&lt;br /&gt;
		$this-&amp;gt;content-&amp;gt;text = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
		$mform = new simplehtml_form();&lt;br /&gt;
&lt;br /&gt;
		//Form processing and displaying is done here&lt;br /&gt;
		if ($mform-&amp;gt;is_cancelled()) {&lt;br /&gt;
			//Handle form cancel operation, if cancel button is present on form&lt;br /&gt;
		} else if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
			//In this case you process validated data. $mform-&amp;gt;get_data() returns data posted in form.&lt;br /&gt;
		} else {&lt;br /&gt;
			// this branch is executed if the form is submitted but the data doesn&#039;t validate and the form should be redisplayed&lt;br /&gt;
			// or on the first display of the form.&lt;br /&gt;
&lt;br /&gt;
			//Set default data (if any)&lt;br /&gt;
			$mform-&amp;gt;set_data($toform);&lt;br /&gt;
&lt;br /&gt;
			//displays the form&lt;br /&gt;
			$this-&amp;gt;content-&amp;gt;text = $mform-&amp;gt;render();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return $this-&amp;gt;content;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Form elements==&lt;br /&gt;
===Basic form elements===&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#button button]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#checkbox checkbox]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#radio radio]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#select select]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#multi-select multi-select]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#password password]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#hidden hidden]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#html html] - div element&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#static static] - Display a static text.&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#text text]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#textarea textarea]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#Use_Fieldsets_to_group_Form_Elements header]&lt;br /&gt;
&lt;br /&gt;
=== Advanced form elements===&lt;br /&gt;
&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#autocomplete Autocomplete] - A select box that allows you to start typing to narrow the list of options, or search for results.&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#advcheckbox advcheckbox] - Advance checkbox&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#float float]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#passwordunmask passwordunmask] - A password element with option to show the password in plaintext.&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#recaptcha recaptcha]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#selectyesno selectyesno]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#selectwithlink selectwithlink]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#date_selector date_selector]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#date_time_selector date_time_selector]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#duration duration]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#editor editor]&lt;br /&gt;
# [https://docs.moodle.org/dev/Using_the_File_API_in_Moodle_forms#filepicker filepicker] - upload single file&lt;br /&gt;
# [https://docs.moodle.org/dev/Using_the_File_API_in_Moodle_forms#filemanager filemanager] - upload multiple files&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#tags tags]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#addGroup addGroup]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#modgrade modgrade]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#modvisible modvisible]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#choosecoursefile choosecoursefile]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#grading grading]&lt;br /&gt;
# [https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#questioncategory questioncategory]&lt;br /&gt;
&lt;br /&gt;
===Custom form elements===&lt;br /&gt;
&lt;br /&gt;
If you need a custom form element you can dynamical register new elements and then use them like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    MoodleQuickForm::registerElementType(&#039;course_competency_rule&#039;,&lt;br /&gt;
                                         &amp;quot;$CFG-&amp;gt;dirroot/$CFG-&amp;gt;admin/tool/lp/classes/course_competency_rule_form_element.php&amp;quot;,&lt;br /&gt;
                                         &#039;tool_lp_course_competency_rule_form_element&#039;);&lt;br /&gt;
    // Reuse the same options.&lt;br /&gt;
    $mform-&amp;gt;addElement(&#039;course_competency_rule&#039;, &#039;competency_rule&#039;, get_string(&#039;uponcoursemodulecompletion&#039;, &#039;tool_lp&#039;), $options);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
&lt;br /&gt;
https://github.com/moodle/moodle/blob/master/admin/tool/lp/lib.php#L157-L161&lt;br /&gt;
&lt;br /&gt;
https://github.com/moodle/moodle/blob/master/admin/tool/lp/classes/course_competency_rule_form_element.php&lt;br /&gt;
&lt;br /&gt;
==Commonly used functions==&lt;br /&gt;
&lt;br /&gt;
====add_action_buttons($cancel = true, $submitlabel=null);====&lt;br /&gt;
&lt;br /&gt;
You will normally use this helper function which is a method of moodleform to add all the &#039;action&#039; buttons to the end of your form. A boolean parameter allow you to specify whether to include a cancel button and specify the label for your submit button (pass the result of get_string). Default for the submit button label is get_string(&#039;savechanges&#039;). Note the &#039;&#039;&#039;$this&#039;&#039;&#039; not &#039;&#039;&#039;$mform&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $this-&amp;gt;add_action_buttons();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#setDefault_2|setDefault()]]====&lt;br /&gt;
To set the default value for an element.&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#disabledIf|disabledIf()]]====&lt;br /&gt;
For any element or groups of element in a form you can conditionally disable the group or individual element depending on conditions.&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#hideIf|hideif()]]====&lt;br /&gt;
For any element or groups of element in a form you can conditionally hide the group or individual element depending on conditions.&lt;br /&gt;
Same syntax as disabledIf. Can do a simple search and replace on disabledIf.  Added in Moodle 3.4.&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#addRule|addRule()]]====&lt;br /&gt;
Add rule for server/client side validation. Like text field is required element and is of type email.&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#setHelpButton|setHelpButton()]]====&lt;br /&gt;
Sets pop-up help button to a form element.&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#addHelpButton|addHelpButton()]]====&lt;br /&gt;
Adds pop-up help button to a form element&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#setType|setType()]]====&lt;br /&gt;
PARAM_* types are used to specify how a submitted variable should be cleaned.&lt;br /&gt;
&lt;br /&gt;
====[[lib/formslib.php_Form_Definition#disable_form_change_checker|disable_form_change_checker()]]====&lt;br /&gt;
By default, any Moodle form will pop-up an &amp;quot;Are you sure?&amp;quot; alert if you make some changes and then try to leave the page without saving. Occasionally, that is undesirable, in which case you can call &amp;lt;tt&amp;gt;$mform-&amp;gt;disable_form_change_checker()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==FAQ==&lt;br /&gt;
[https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#Use_Fieldsets_to_group_Form_Elements How to group elements]&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Core_APIs]]&lt;br /&gt;
* [[lib/formslib.php_Usage]] &lt;br /&gt;
* [[lib/formslib.php_Form_Definition]]&lt;br /&gt;
* [[Designing usable forms]]&lt;br /&gt;
* [[Fragment]]&lt;br /&gt;
* [[MForm_Modal]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Cschoeffel</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Running_acceptance_test&amp;diff=57667</id>
		<title>Running acceptance test</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Running_acceptance_test&amp;diff=57667"/>
		<updated>2020-06-28T21:20:56Z</updated>

		<summary type="html">&lt;p&gt;Cschoeffel: Added instructions to run behat tests on a local browser with a remote moodle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Short version ==&lt;br /&gt;
&lt;br /&gt;
...or how I got it to work on Ubuntu and some of the problems encountered. &lt;br /&gt;
&lt;br /&gt;
You need a bunch of browsers and terminal windows open to do this.&lt;br /&gt;
&lt;br /&gt;
==== 1. Background ====  &lt;br /&gt;
&lt;br /&gt;
# I am using the desktop version of Ubuntu 17.04 so there are no issues about running this software in headless mode. Running in headless mode was not tested.&lt;br /&gt;
# Moodle is version 3.3 and is a fully installed and working version using the &#039;standard&#039; Ubuntu LAMP stack.&lt;br /&gt;
&lt;br /&gt;
==== 2. Set up Selenium ====&lt;br /&gt;
First, you should have a look at [[Acceptance_testing/Browsers/Working_combinations_of_OS%2BBrowser%2Bselenium#Working_combinations_of_OS.2BBrowser.2Bselenium|working combinations of OS+Browser+selenium]].&lt;br /&gt;
&lt;br /&gt;
# Download the Selenium Standalone Server from [http://www.seleniumhq.org/download/ http://www.seleniumhq.org/download/]. It&#039;s a single JAR file, put it anywhere handy.&lt;br /&gt;
# Download the Chrome driver from [https://sites.google.com/a/chromium.org/chromedriver/ https://sites.google.com/a/chromium.org/chromedriver/]. Ensure you have the right version of the Chrome driver - see [[#Trouble_shooting| Trouble shooting]]. (Firefox is currently problematic. See [[Actual_Selenium_with_old_Firefox_47.0.1]] if you need to try to make it work.)&lt;br /&gt;
# Unzip the driver (it&#039;s a single file) and copy to /usr/local/bin (should work anywhere on the path)&lt;br /&gt;
# If not installed already, &#039;&amp;lt;tt&amp;gt;sudo apt install default-jre&amp;lt;/tt&amp;gt;&#039;&lt;br /&gt;
# Start Selenium - &#039;&amp;lt;tt&amp;gt;java -jar /path/to/your/selenium/server/selenium-server-standalone-N.NN.N.jar -port 4444&amp;lt;/tt&amp;gt;&#039;&lt;br /&gt;
# check it works, access &#039;localhost:4444/wd/hub/&#039; in your browser and check you can create a new Chrome session.&lt;br /&gt;
&lt;br /&gt;
If running headless or the above doesn&#039;t work (&amp;quot;Selenium server is not running&amp;quot; when running the behat tests). Try the following&lt;br /&gt;
# Run &#039;&amp;lt;tt&amp;gt;Xvfb -ac :99 -screen 0 1280x1024x16 &amp;amp;&amp;lt;/tt&amp;gt;&#039;&lt;br /&gt;
# Then immediately, &#039;&amp;lt;tt&amp;gt;export DISPLAY=:99&amp;lt;/tt&amp;gt;&#039;&lt;br /&gt;
# The run the Selenium command as above&lt;br /&gt;
&lt;br /&gt;
==== 3. Set up Moodle ====&lt;br /&gt;
&lt;br /&gt;
# Create a new &#039;dataroot&#039; area for files especially for behat adjusting permissions accordingly. &lt;br /&gt;
# If not there already, add Section 11 from config-dist.php to your config.php file and review the settings. &lt;br /&gt;
# $CFG-&amp;gt;behat_wwwroot needs to point to your Moodle site yet be different from the &#039;normal&#039; wwwroot (e.g. if you used localhost for wwwroot use 127.0.0.1 for the behat_wwwroot). Whatever you choose, make sure it works. &lt;br /&gt;
# $CFG-&amp;gt;behat_dataroot should point to the directory you created above&lt;br /&gt;
# $CFG-&amp;gt;behat_prefix should be fine. &lt;br /&gt;
# Set up $CFG-&amp;gt;behat_profiles to select Chrome as the browser...&lt;br /&gt;
&lt;br /&gt;
     $CFG-&amp;gt;behat_profiles = [&lt;br /&gt;
         &#039;default&#039; =&amp;gt; [&lt;br /&gt;
             &#039;browser&#039; =&amp;gt; &#039;chrome&#039;,&lt;br /&gt;
             &#039;extensions&#039; =&amp;gt; [&lt;br /&gt;
                 &#039;Behat\MinkExtension&#039; =&amp;gt; [&lt;br /&gt;
                     &#039;selenium2&#039; =&amp;gt; [&lt;br /&gt;
                         &#039;browser&#039; =&amp;gt; &#039;chrome&#039;,&lt;br /&gt;
                     ]&lt;br /&gt;
                 ]&lt;br /&gt;
             ]&lt;br /&gt;
         ]&lt;br /&gt;
     ];&lt;br /&gt;
&lt;br /&gt;
==== 4. Configure Behat for Moodle ====&lt;br /&gt;
&lt;br /&gt;
# Run &#039;&amp;lt;tt&amp;gt;php admin/tool/behat/cli/init.php&amp;lt;/tt&amp;gt;&#039; (from the root of your Moodle install). This installs all the required software and creates the test version of Moodle. &lt;br /&gt;
&lt;br /&gt;
==== 5. Run Behat tests ====&lt;br /&gt;
&lt;br /&gt;
# Run &#039;&amp;lt;tt&amp;gt;vendor/bin/behat&amp;lt;/tt&amp;gt;&#039;. If you don&#039;t want to run all the tests add &#039;&amp;lt;tt&amp;gt;--tags=&amp;quot;@something&amp;quot;&amp;lt;/tt&amp;gt;&#039; where the @something refers to the tags at the top of most feature files. Use comma-separated list like &#039;&amp;lt;tt&amp;gt;@some_thing,@some_thing_else&amp;lt;/tt&amp;gt;&#039; to run tests from multiple areas. See upstream documentation on Gherkin filters for advanced syntax and more complex examples.&lt;br /&gt;
# After some initial setup dots should start to go by. It&#039;s a while before Selenium is first accessed. On the Linux desktop a new Chrome window appears and the testing process &#039;remote control&#039; starts (hopefully!)&lt;br /&gt;
&lt;br /&gt;
== Prerequisite ==&lt;br /&gt;
Before initializing acceptance test environment for running behat, you should ensure:&lt;br /&gt;
# [[Acceptance_testing#Requirements Meet min. system requirements for running tests]]&lt;br /&gt;
# [[Acceptance_testing#Installation Have set min. config variable in config.php for behat]]&lt;br /&gt;
# [[Acceptance_testing#Installation Downloaded composer dependencies]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Acceptance tests (also known as behat), use [http://www.seleniumhq.org/download/ Selenium server] and can be run as:&lt;br /&gt;
# &#039;&#039;&#039;Single run:&#039;&#039;&#039; In single run, only one behat run is executed. So all features are executed in this single run.&lt;br /&gt;
# &#039;&#039;&#039;Parallel runs:&#039;&#039;&#039; (Since Moodle 3.0) Parallel runs allow dev&#039;s to execute multiple behat runs together. This was introduced to get acceptance tests results faster. To achieve this:&lt;br /&gt;
#* Features are divided between multiple behat runs&lt;br /&gt;
#* Symlinks behatrun{x} (x being the run process number), are created pointing to moodle directory, so site for run 1 is accessible via https://localhost/moodle/behatrun1&lt;br /&gt;
#* Process number is included as suffix to $CFG-&amp;gt;behat_prefix.&lt;br /&gt;
#* Process number is suffixed to $CFG-&amp;gt;behat_dataroot.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Initialise acceptance test environment ==&lt;br /&gt;
Before running acceptance tests, environment needs to be initialised for acceptance testing.&lt;br /&gt;
&lt;br /&gt;
=== Single run ===&lt;br /&gt;
For initialising acceptance tests for single run, above command is sufficient.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
php admin/tool/behat/cli/init.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Parallel runs ===&lt;br /&gt;
For initialising acceptance tests for parallel runs, you can use one of the following options&lt;br /&gt;
# &#039;&#039;&#039;-j=&amp;lt;number&amp;gt; or --parallel=&amp;lt;number&amp;gt;&#039;&#039;&#039; (required) Number of parallel behat run to initialise&lt;br /&gt;
# &#039;&#039;&#039;-m=&amp;lt;number&amp;gt; or --maxruns=&amp;lt;number&amp;gt;&#039;&#039;&#039;  (optional) Max parallel site which should be initialised at one time. If your system is slow, then you can initialise sites in chucks.&lt;br /&gt;
# &#039;&#039;&#039;--fromrun=&amp;lt;number&amp;gt;&#039;&#039;&#039; (optional) Initialise site to run specified run from. Used for running acceptance tests on different vms&lt;br /&gt;
# &#039;&#039;&#039;--torun=&amp;lt;number&amp;gt;&#039;&#039;&#039; (optional) Initialise site to run specified run till. Used for running acceptance tests on different vms&lt;br /&gt;
# &#039;&#039;&#039;-o or --optimize-runs&#039;&#039;&#039; (optional) This option will split features with specified tags in all parallel runs, so they are executed first when parallel run gets executed.&lt;br /&gt;
# &#039;&#039;&#039;-a=&amp;lt;name&amp;gt; or --add-core-features-to-theme=&amp;lt;name&amp;gt;&#039;&#039;&#039; (optional) Since Moodle 3.2. Use this option to add all core features to specified themes (comma separated list of themes)&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Below command will initialise moodle to run 2 parallel tests.&lt;br /&gt;
php admin/tool/behat/cli/init.php --parallel=2&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 2: Running acceptance test environment ==&lt;br /&gt;
=== Single run ===&lt;br /&gt;
Run either of the following commands. For more options &#039;&#039;&#039;vendor/bin/behat --help&#039;&#039;&#039; or http://docs.behat.org/guides/6.cli.html&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
vendor/bin/behat --config /path/to/your/CFG_behat_dataroot/behatrun/behat/behat.yml&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You almost always want to limit the number of tests that are run. To run all the tests in one plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
vendor/bin/behat --config /path/to/your/CFG_behat_dataroot/behatrun/behat/behat.yml --tags mod_myplugin&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To run all the tests in one .feature file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
vendor/bin/behat --config /path/to/your/CFG_behat_dataroot/behatrun/behat/behat.yml /path/to/moodle/mod/myplugin/tests/behat/testsomething.feature&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To run a single scenario:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
vendor/bin/behat --config /path/to/your/CFG_behat_dataroot/behatrun/behat/behat.yml /path/to/moodle/mod/myplugin/tests/behat/testsomething.feature:40&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, &#039;40&#039; is the line-number of the feature file where the Scenario starts.&lt;br /&gt;
&lt;br /&gt;
=== Parallel runs ===&lt;br /&gt;
For running parallel runs, use following command&lt;br /&gt;
&lt;br /&gt;
 php admin/tool/behat/cli/run.php&lt;br /&gt;
&lt;br /&gt;
Following optional options are available for custom run:&lt;br /&gt;
# &#039;&#039;&#039;--feature&#039;&#039;&#039; Only execute specified feature file (Absolute path of feature file).&lt;br /&gt;
# &#039;&#039;&#039;--suite&#039;&#039;&#039; Features for specified theme will be executed.&lt;br /&gt;
# &#039;&#039;&#039;--replace&#039;&#039;&#039; Replace args string with run process number, useful for output and reruns.&lt;br /&gt;
# &#039;&#039;&#039;--fromrun&#039;&#039;&#039; Execute run starting from (Used for parallel runs on different vms)&lt;br /&gt;
# &#039;&#039;&#039;--torun&#039;&#039;&#039; Execute run till (Used for parallel runs on different vms)&lt;br /&gt;
# Behat options can be passed for filtering features/scenarios:&lt;br /&gt;
#* In case you don&#039;t want to run Javascript tests, use the Behat tags option to skip them, &#039;&#039;&#039;--tags=&amp;quot;~@javascript&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
#* In case you want to run specific scenario, use the Behat name option to run it, &#039;&#039;&#039;--name=&amp;quot;Filter user accounts by role and cohort&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
#* In case you want to run specific feature file, use the Behat feature option to run it, &#039;&#039;&#039;--feature=&amp;quot;/PATH/TO/MOODLE/admin/tests/behat/filter_users.feature&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Example: Initialise and run Behat tests for a custom plugin under a custom theme:&lt;br /&gt;
&lt;br /&gt;
 php admin/tool/behat/cli/init.php --parallel=3 --add-core-features-to-theme=&amp;quot;mytheme&amp;quot;&lt;br /&gt;
 php admin/tool/behat/cli/run.php --tags=&amp;quot;@tool_myplugin&amp;quot; --suite=&amp;quot;mytheme&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Common options for running tests ===&lt;br /&gt;
==== Tests filters ====&lt;br /&gt;
With the &#039;&#039;&#039;--tags&#039;&#039;&#039; or the &#039;&#039;&#039;-name&#039;&#039;&#039; Behat options you can filter which tests are going to run or which ones are going to be skipped. There are a few tags that you might be interested in:&lt;br /&gt;
* &#039;&#039;&#039;@javascript&#039;&#039;&#039;: All the tests that runs in a browser using Javascript; they require Selenium to be running, otherwise an exception will be thrown.&lt;br /&gt;
* &#039;&#039;&#039;@_file_upload&#039;&#039;&#039;: All the tests that involves file uploading or any OS feature that is not 100% part of the browser. They should only be executed when Selenium is running in the same machine where the tests are running.&lt;br /&gt;
* &#039;&#039;&#039;@_alert&#039;&#039;&#039;: All the tests that involves Javascript dialogs (alerts, confirms...) are using a feature that is OS-dependant and out of the browser scope, so they should be tag appropriately as not all browsers manage them properly.&lt;br /&gt;
* &#039;&#039;&#039;@_switch_window&#039;&#039;&#039;: All the tests that are using the &#039;&#039;&#039;I switch to &amp;quot;NAME&amp;quot; window&#039;&#039;&#039; step should be tagged as not all browsers manage them properly.&lt;br /&gt;
* &#039;&#039;&#039;@_switch_iframe&#039;&#039;&#039;: All the tests that are using the &#039;&#039;&#039;I switch to &amp;quot;NAME&amp;quot; iframe&#039;&#039;&#039; steps should be tagged as it is an advanced feature and some browsers may have problems dealing with them&lt;br /&gt;
* &#039;&#039;&#039;@_cross_browser&#039;&#039;&#039;: All the tests that should run against multiple combinations of browsers + OS in a regular basis. The features that are sensitive to different combinations of OS and browsers should be tagges as @_cross_browser.&lt;br /&gt;
* &#039;&#039;&#039;@componentname&#039;&#039;&#039;: Moodle features uses the [https://docs.moodle.org/dev/Frankenstyle Frankenstyle] component name to tag the features according to the Moodle subsystem they belong to.&lt;br /&gt;
&lt;br /&gt;
==== Output formats ====&lt;br /&gt;
Since Moodle 3.1 option for output is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
--format=pretty --out=/path/to/pretty.txt --format=moodle_progress --out=std&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Before Moodle 3.1 option for output was:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
--format=&#039;moodle_progress,pretty&#039; --out=&#039;,/path/to/pretty.txt&#039;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Following output formats are supported:&lt;br /&gt;
# &#039;&#039;&#039;progress&#039;&#039;&#039;: Prints one character per step.&lt;br /&gt;
# &#039;&#039;&#039;pretty&#039;&#039;&#039;: Prints the feature as is.&lt;br /&gt;
# &#039;&#039;&#039;junit&#039;&#039;&#039;: Outputs the failures in JUnit compatible files.&lt;br /&gt;
# &#039;&#039;&#039;moodle_progress&#039;&#039;&#039;: Prints Moodle branch information and dots for each step.&lt;br /&gt;
# &#039;&#039;&#039;moodle_list&#039;&#039;&#039;: List all scenarios.&lt;br /&gt;
# &#039;&#039;&#039;moodle_stepcount&#039;&#039;&#039;: List all features with total steps in each feature file. Used for parallel run.&lt;br /&gt;
# &#039;&#039;&#039;moodle_screenshot&#039;&#039;&#039;: (since Moodle 3.1) Take screenshot and core dump of each step. With following options you can dump either or both.&lt;br /&gt;
## --format-settings &#039;{&amp;quot;formats&amp;quot;: &amp;quot;image&amp;quot;}&#039;**: will dump image only&lt;br /&gt;
## --format-settings &#039;{&amp;quot;formats&amp;quot;: &amp;quot;html&amp;quot;}&#039;**: will dump html only.&lt;br /&gt;
## --format-settings &#039;{&amp;quot;formats&amp;quot;: &amp;quot;html,image&amp;quot;}&#039;**: will dump both.&lt;br /&gt;
## --format-settings &#039;{&amp;quot;formats&amp;quot;: &amp;quot;html&amp;quot;, &amp;quot;dir_permissions&amp;quot;: &amp;quot;0777&amp;quot;}&#039;**&lt;br /&gt;
If you want to see the failures immediately (rather than waiting ~3 hours for all the tests to finish) then either use the -v option to output a bit more information, or change the output format using --format. Format &#039;pretty&#039; (&#039;&#039;&#039;-f pretty&#039;&#039;&#039;) is sufficient for most cases, as it outputs each step outcomes in the command line making easier to see the progress.&lt;br /&gt;
&lt;br /&gt;
== Advance usage ==&lt;br /&gt;
=== Rerun failed scenarios ===&lt;br /&gt;
With slow systems or parallel run you might see some random failures, to rerun only failed scenarios (to eliminate random failures), use --rerun option&lt;br /&gt;
# &#039;&#039;&#039;Single run:&#039;&#039;&#039; --run=&amp;quot;absolute_path_to_empty_file&amp;quot; (Behat will record failed scenarios in this file, and when run again only failed scenarios will be run)&lt;br /&gt;
# &#039;&#039;&#039;Parallel run:&#039;&#039;&#039; --rerun=&amp;quot;absolute_path_to_empty_file_{runprocess}.txt --replace=&amp;quot;{runprocess}&amp;quot; ({runprocess} will be replaced with the process number for recording fails in the specific run process).&lt;br /&gt;
&#039;&#039;&#039;Since Moodle 3.1 --rerun option don&#039;t accept any value, as it is handled internally by behat&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Running behat with specified theme (Since Moodle 3.2) ===&lt;br /&gt;
You can run behat with any theme installed. To execute behat with specified theme use &#039;&#039;&#039;--suite={THEME_NAME}&#039;&#039;&#039; option, while running behat. By default the features in theme behat folder will be executed for the suite. But if you want to run all core features with the specific theme then initialise acceptance test with --add-core-features-to-theme={THEME_NAME}, e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
php admin/tool/behat/cli/init.php --add-core-features-to-theme=clean&lt;br /&gt;
vendor/bin/behat --suite=clean --tags=&amp;quot;@enrol_foobar&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is a core theme but it will work with custom theme. No = or quotes needed around the theme name.&lt;br /&gt;
&lt;br /&gt;
Make sure that &amp;lt;tt&amp;gt;$CFG-&amp;gt;theme&amp;lt;/tt&amp;gt; is &#039;&#039;&#039;not set&#039;&#039;&#039; in your config.php.&lt;br /&gt;
&lt;br /&gt;
==== Override behat core context for theme suite ====&lt;br /&gt;
To override behat step definitions so as to run behat with specified theme, you should create a contexts within &#039;&#039;&#039;/theme/{MYTHEME}/tests/behat/&#039;&#039;&#039; with prefix behat_theme_{MYTHEME}_ and suffixed with the context being overridden. For example, if you want to override behat_mod_forum context, then you should create a class /theme/{MYTHEME}/tests/behat/mod_forum/behat_theme_{MYTHEME}_behat_mod_forum.php&lt;br /&gt;
&lt;br /&gt;
==== Blacklist behat context or features to run in theme suite ====&lt;br /&gt;
To blacklist contexts/ features to be executed by theme suite you should create a /theme/{MYTHEME}/tests/behat/blacklist.json file with following format. Following will not use step_definitions from  behat_grade and behat_navigation while running theme suite. Also, scenarios in auth/tests/behat/login.feature and grade/tests/behat/grade_hidden_items.feature won&#039;t be executed with theme suite.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;contexts&amp;quot;: [&lt;br /&gt;
    &amp;quot;behat_grade&amp;quot;,&lt;br /&gt;
    &amp;quot;behat_navigation&amp;quot;,&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;features&amp;quot;: [&lt;br /&gt;
    &amp;quot;auth/tests/behat/login.feature&amp;quot;,&lt;br /&gt;
    &amp;quot;grade/tests/behat/grade_hidden_items.feature&amp;quot;,&lt;br /&gt;
   ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==== Override core behat selectors ====&lt;br /&gt;
To override behat selectors in specific theme, you should create a class behat_theme_{MYTHEME}_behat_selectors in /theme/{MYTHEME}/tests/behat/behat_theme_{MYTHEME}_behat_selectors.php extending behat_selectors.&lt;br /&gt;
&lt;br /&gt;
=== Use php built in web server ===&lt;br /&gt;
You can use php built-in-web server for executing behat runs. To do so:&lt;br /&gt;
# Open a command line interface and &#039;&#039;&#039;cd /to/your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;php -S localhost:8000&#039;&#039;&#039; (This is the test site URL that moodle uses by default, if you want to use another one you can override it in config.php with $CFG-&amp;gt;behat_wwwroot attribute; more info in https://docs.moodle.org/dev/Acceptance_testing#Advanced_usage or config-dist.php)&lt;br /&gt;
# Update $CFG-&amp;gt;behat_wwwroot = localhost:8000; in config.php&lt;br /&gt;
&lt;br /&gt;
=== Define custom options for parallel runs ===&lt;br /&gt;
You can set following custom config options for parallel runs via $CFG-&amp;gt;behat_parallel_run. It&#039;s an array of options where 1st array is for 1st run and so on.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
       array (&lt;br /&gt;
           &#039;dbtype&#039; =&amp;gt; &#039;mysqli&#039;,&lt;br /&gt;
           &#039;dblibrary&#039; =&amp;gt; &#039;native&#039;,&lt;br /&gt;
           &#039;dbhost&#039; =&amp;gt; &#039;localhost&#039;,&lt;br /&gt;
           &#039;dbname&#039; =&amp;gt; &#039;moodletest&#039;,&lt;br /&gt;
           &#039;dbuser&#039; =&amp;gt; &#039;moodle&#039;,&lt;br /&gt;
           &#039;dbpass&#039; =&amp;gt; &#039;moodle&#039;,&lt;br /&gt;
           &#039;behat_prefix&#039; =&amp;gt; &#039;mdl_&#039;,&lt;br /&gt;
           &#039;wd_host&#039; =&amp;gt; &#039;http://127.0.0.1:4444/wd/hub&#039;,&lt;br /&gt;
           &#039;behat_wwwroot&#039; =&amp;gt; &#039;http://127.0.0.1/moodle&#039;,&lt;br /&gt;
           &#039;behat_dataroot&#039; =&amp;gt; &#039;/home/example/bht_moodledata&#039;&lt;br /&gt;
       )&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To set different selenium servers for parallel runs, you can use following. NOTE: Running parallel (headless) runs on different selenium servers avoid random focus failures.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    $CFG-&amp;gt;behat_parallel_run = array (&lt;br /&gt;
        array (&#039;wd_host&#039; =&amp;gt; &#039;http://127.0.0.1:4444/wd/hub&#039;),&lt;br /&gt;
        array (&#039;wd_host&#039; =&amp;gt; &#039;http://127.0.0.1:4445/wd/hub&#039;),&lt;br /&gt;
        array (&#039;wd_host&#039; =&amp;gt; &#039;http://127.0.0.1:4446/wd/hub&#039;),&lt;br /&gt;
    );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write new tests and behat methods ===&lt;br /&gt;
&lt;br /&gt;
If you want to write tests for your own integration, you can do so by creating new tests with format .feature. Follow instructions in [[Writing_acceptance_tests|this page]] to write new tests. &lt;br /&gt;
&lt;br /&gt;
It is also possible to add new steps the moodle behat integration. In order to do so, you will have to create a new .php class with the prefix &#039;&#039;&#039;behat_&#039;&#039;&#039;. Copy the format from &#039;&#039;&#039;lib\behat\behat_base.php&#039;&#039;&#039;, but set your class to extend the behat_base class instead of the MinkExtension. You can define new behat steps by declaring functions with the appropriate heading. &lt;br /&gt;
&lt;br /&gt;
You will not be  able to use these steps and features right away. Check [[Running_acceptance_test#New_step_definitions_or_features_are_not_executed|this section]] for instructions on how to update the behat integration. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For further information on how to create new steps definitions, check [[Acceptance testing/Custom acceptance steps]].&lt;br /&gt;
&lt;br /&gt;
=== Running acceptance tests with different browser ===&lt;br /&gt;
&lt;br /&gt;
If you follow the steps above, Behat will run with Chrome.&lt;br /&gt;
&lt;br /&gt;
You can get it to run with other browsers. The basic idea is to expand the $CFG-&amp;gt;behat_profiles array in config.php to list more browsers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;behat_profiles = array(&lt;br /&gt;
   &#039;chrome&#039; =&amp;gt; array(&lt;br /&gt;
       &#039;browser&#039; =&amp;gt; &#039;chrome&#039;,&lt;br /&gt;
       &#039;tags&#039; =&amp;gt; &#039;@javascript&#039;,&lt;br /&gt;
   )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Acceptance_testing/Browsers|More info about alternative browsers]]&lt;br /&gt;
&lt;br /&gt;
=== Start multiple selenium servers ===&lt;br /&gt;
From command line Start selenium servers at different ports (say 4444, 4445, 4446 for 3 parallel runs)&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar -port 4444 &amp;amp;&lt;br /&gt;
java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar -port 4445 &amp;amp;&lt;br /&gt;
java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar -port 4446&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternative way of running three Selenium servers in parallel:&lt;br /&gt;
&lt;br /&gt;
 $ printf %d\\n {4444..4446} | xargs -n 1 -P 3 java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar -port&lt;br /&gt;
&lt;br /&gt;
=== Run tests directly in Chrome, with no Selenium ===&lt;br /&gt;
&lt;br /&gt;
Historically, the tests would talk to a Selenium server, which would then tell the target browser what to do. More and more, the browsers themselves contain such a server and you can talk to them directly, which is faster and easier. Work was done to get this working with Chrome in MDL-58948, but it still needs some further setup to get it working, which is detailed in the bug ticket, and which I&#039;ll copy below:&lt;br /&gt;
&lt;br /&gt;
Replace your current behat config with the abve, the api_url is where you&#039;ll talk directly to your Chrome browser.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;behat_config = [&lt;br /&gt;
    &#039;default&#039; =&amp;gt; [&lt;br /&gt;
        &#039;extensions&#039; =&amp;gt; [&lt;br /&gt;
            &#039;DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension&#039; =&amp;gt; [],&lt;br /&gt;
            &#039;Behat\MinkExtension&#039;                                          =&amp;gt; [&lt;br /&gt;
                &#039;browser_name&#039; =&amp;gt; &#039;chrome&#039;,&lt;br /&gt;
                &#039;base_url&#039;     =&amp;gt; $CFG-&amp;gt;behat_wwwroot,&lt;br /&gt;
                &#039;goutte&#039;       =&amp;gt; null,&lt;br /&gt;
                &#039;selenium2&#039;    =&amp;gt; null,&lt;br /&gt;
                &#039;sessions&#039;     =&amp;gt; [&lt;br /&gt;
                    &#039;javascript&#039; =&amp;gt; [&lt;br /&gt;
                        &#039;chrome&#039; =&amp;gt; [&lt;br /&gt;
                            &#039;api_url&#039; =&amp;gt; &#039;http://localhost:9222&#039;&lt;br /&gt;
                        ]&lt;br /&gt;
                    ]&lt;br /&gt;
                ]&lt;br /&gt;
            ]&lt;br /&gt;
        ]&lt;br /&gt;
    ],&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use composer to install two more required libraries:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
composer require --dev dmore/behat-chrome-extension&lt;br /&gt;
composer require --dev dmore/chrome-mink-driver&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you try to run the tests it will tell you that Chrome isn&#039;t running, in a second tab run the following to start Chrome (or chromium-browser on Ubuntu)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chrome --disable-gpu --headless --remote-debugging-address=0.0.0.0 --remote-debugging-port=9222&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is running headless so you won&#039;t see any windows pop up as the tests run, though it runs in the other mode too.&lt;br /&gt;
&lt;br /&gt;
Behat should now run as before, but faster.&lt;br /&gt;
&lt;br /&gt;
==== Run Chrome locally with Behat and Moodle on a remote server ====&lt;br /&gt;
If you have Moodle running on a remote (headless) server, but don&#039;t want to install a window manager, you can do the following:&lt;br /&gt;
&lt;br /&gt;
1. Go through all the steps from above&lt;br /&gt;
&lt;br /&gt;
2. Establish an SSH SOCKS5 proxy connection to your server:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -D VARIABLE-PORT-A -N -q -C USER@SERVER&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Forward the port to connect to the DevTools-API of your browser:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -R VARIABLE-PORT-B:localhost:VARIABLE-PORT-B USER@SERVER -N -q -C&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Tell your local Chrome to use custom settings:&lt;br /&gt;
&amp;lt;code&amp;gt;/path/to/Google\ Chrome [--disable-gpu] --remote-debugging-address=0.0.0.0 --remote-debugging-port=VARIABLE-PORT-B --proxy-server=socks://127.0.0.1:VARIABLE-PORT-A --proxy-bypass-list=&#039;&amp;lt;-loopback&amp;gt;&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or, all in one command:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -D VARIABLE-PORT-A -N -q -C -f USER@SERVER &amp;amp;&amp;amp; ssh -R VARIABLE-PORT-B:localhost:VARIABLE-PORT-B USER@SERVER -N -q -C -f &amp;amp;&amp;amp; /path/to/Google\ Chrome [--disable-gpu] --remote-debugging-address=0.0.0.0 --remote-debugging-port=VARIABLE-PORT-B --proxy-server=socks://127.0.0.1:VARIABLE-PORT-A --proxy-bypass-list=&#039;&amp;lt;-loopback&amp;gt;&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation for the SSH settings:&lt;br /&gt;
* VARIABLE-PORT-B &amp;amp; VARIABLE-PORT-A : Choose these as you like. Bear in mind that you will need root rights if the port number is 1023 or lower&lt;br /&gt;
* -N: Tells SSH not to open an actual command prompt&lt;br /&gt;
* -C: Compress all data passed through the tunnel&lt;br /&gt;
* -q: Quiet mode. Causes most warning and diagnostic messages to be suppressed&lt;br /&gt;
*-R: Open a tunnel binding to localhost on the remote machine, going to localhost on the local machine&lt;br /&gt;
* -f: Fork the process into background&lt;br /&gt;
&lt;br /&gt;
Explanation for the Chrome settings:&lt;br /&gt;
* --proxy-bypass-list=&#039;&amp;lt;-loopback&amp;gt;&#039; : Tells Chrome to send requests to localhost through the tunnel&lt;br /&gt;
* --proxy-server=socks://127.0.0.1:VARIABLE-PORT-A : To use the SOCKS5 tunnel we just set up&lt;br /&gt;
* --remote-debugging-port=VARIABLE-PORT-B &amp;amp; --remote-debugging-address=0.0.0.0 : To use the SSH tunnel we just set up&lt;br /&gt;
&lt;br /&gt;
=== Using Docker to start selenium server ===&lt;br /&gt;
==== What is Docker ====&lt;br /&gt;
Docker is a app container,  it&#039;s a kind of virtual machine, but only for one app, service,  so you can download&lt;br /&gt;
a docker image and run a selenium server without worry in how to configure selenium in your machine, one for chrome, others for firefox, you either don&#039;t need to install the browsers in your machine&lt;br /&gt;
To install docker follow this link; https://docs.docker.com/engine/installation/&lt;br /&gt;
&lt;br /&gt;
==== Selenium docker images ====&lt;br /&gt;
There is many docker images available,  for many browser, the complete list is in https://hub.docker.com/u/selenium/&lt;br /&gt;
for moodle you can use standalone version.&lt;br /&gt;
You can download  specific selenium version too,  for example,  for firefox,  moodle recommend selenium 2.53.1, see: [https://docs.moodle.org/dev/Acceptance_testing/Browsers/Working_combinations_of_OS%2BBrowser%2Bselenium What version do I need?]&lt;br /&gt;
&lt;br /&gt;
so  the command will be:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
docker run -d -p4444:4444 selenium/standalone-firefox:2.53.1-beryllium&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to see all available version click in tags.   For firefox you can find at: https://hub.docker.com/r/selenium/standalone-firefox/tags/&lt;br /&gt;
&lt;br /&gt;
==== Change config.php file ====&lt;br /&gt;
In config.php file you must change the $CFG-&amp;gt;behat_wwwroot=   to your network card (NIC) ip address,  you can&#039;t use &lt;br /&gt;
localhost , 127.0.0.1, ...  or selenium docker server  will fail&lt;br /&gt;
&lt;br /&gt;
=== Increasing timeouts ===&lt;br /&gt;
&lt;br /&gt;
You may see errors such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
Javascript code and/or AJAX requests are not ready after 10 seconds. &lt;br /&gt;
There is a Javascript error or the code is extremely slow.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes this indicates a genuine problem with the code, but if you are using a slow computer, it could just mean that the browser was not yet ready. You may find that the test works if you run it again. If you get this error frequently, it might be useful to increase the timeout.&lt;br /&gt;
&lt;br /&gt;
It is possible to increase this timeout by adding a line in your config.php. (Requires Moodle versions 3.5 (from 3.5.6), 3.6 (from 3.6.4), or 3.7+.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;behat_increasetimeout = 2;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will increase all the timeouts by a factor of 2; if that isn&#039;t sufficient, you could use 3. &lt;br /&gt;
&lt;br /&gt;
Increasing timeouts will make tests run a bit slower (because there are points where Behat waits up to a timeout to make sure something doesn&#039;t happen) so don&#039;t do this unless you need to.&lt;br /&gt;
&lt;br /&gt;
== NOTE ==&lt;br /&gt;
# Start the Selenium server (in case you want to run tests that involves Javascript)&lt;br /&gt;
#* (See http://www.installationpage.com/selenium/how-to-run-selenium-headless-firefox-in-ubuntu/ for running &#039;headless&#039; Firefox and xvfm in a server environment)&lt;br /&gt;
#* Open another command line interface and &#039;&#039;&#039;java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Disable acceptance test environment ===&lt;br /&gt;
if you want to prevent access to test environment&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
php admin/tool/behat/cli/util.php --disable&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note that if you have the HTTP_PROXY environment variable set, which you may have had to do to run composer, then you also need to set NO_PROXY=localhost.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Trouble shooting ==&lt;br /&gt;
&lt;br /&gt;
=== New step definitions or features are not executed === &lt;br /&gt;
If you are adding new tests or steps definitions update the tests list&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
php admin/tool/behat/cli/util.php --enable&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039; For parallel runs, all options for initialising parallel runs are valid &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Tests are failing ===&lt;br /&gt;
&lt;br /&gt;
If you followed all the steps and you receive an unknown weird error probably your browser version is not compatible with the Selenium version you are running.  Please refer Working combinations to ensure you have correct [[Acceptance_testing/Browsers#Working_combinations_of_OS.2BBrowser.2Bselenium]] of them to run acceptance test.&lt;br /&gt;
&lt;br /&gt;
=== The tests are failing, and the error message is completely useless ===&lt;br /&gt;
&lt;br /&gt;
For example, it just says &amp;quot;Error writing to database&amp;quot; with no stack trace.&lt;br /&gt;
&lt;br /&gt;
Add -vv command-line option to get very verbose output.&lt;br /&gt;
&lt;br /&gt;
=== Errors during setup (before test are launched) ===&lt;br /&gt;
Typical errors are:&lt;br /&gt;
* Behat requirement not satisfied: http://127.0.0.1/m/stable_master is not available, ensure you specified correct url and that the server is set up and started.&lt;br /&gt;
* Behat is configured but not enabled on this test site.&lt;br /&gt;
&lt;br /&gt;
In order to fix those errors please check that: the behat_dataroot has correct write permissions and that the $CFG-&amp;gt;behat* variables are placed before the lib/setup.php include:&lt;br /&gt;
 require_once(__DIR__ . &#039;/lib/setup.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Selenium server is not running ===&lt;br /&gt;
==== Chrome specific ====&lt;br /&gt;
&lt;br /&gt;
If you are using chrome, you need to ensure that the driver matches the version of the installed chrome browser – which may change on OS updates/upgrades.  Moodle or Selenium will not give the appropriate message – see [https://tracker.moodle.org/browse/MDL-67659/ MDL-67659].  One solution is the one suggested in the issue and use Andrew Nicols’ [https://github.com/andrewnicols/chromedriver-wrapper/  Chromedriver Wrapper] which will ensure you have the appropriate driver before running the tests.&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
* Vagrant profile with Moodle and Behat preconfigured: https://github.com/mackensen/moodle-hat&lt;br /&gt;
* Docker containers for Moodle Developers and Behat: https://github.com/moodlehq/moodle-docker&lt;br /&gt;
* Docker environment with Behat preconfigured : https://github.com/tobiga/docker_moodle_environment&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Acceptance testing for the mobile app]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Quality Assurance]][[Category:Behat]]&lt;/div&gt;</summary>
		<author><name>Cschoeffel</name></author>
	</entry>
</feed>