Merge branch 'MDL-66979-310-7' of git://github.com/andrewnicols/moodle into MOODLE_310_STABLE

This commit is contained in:
Eloy Lafuente (stronk7)
2021-01-26 22:45:23 +01:00
31 changed files with 1145 additions and 968 deletions
+1
View File
@@ -46,6 +46,7 @@ $string['stepsdefinitionstype'] = 'Type';
$string['theninfo'] = 'Then. Checkings to ensure the outcomes are the expected ones';
$string['unknownexceptioninfo'] = 'There was a problem with Selenium or your browser. Please ensure you are using the latest version of Selenium. Error:';
$string['viewsteps'] = 'Filter';
$string['warndirrootconfigfound'] = 'A configuration file was found at {$a}. This file is not automatically updated and may become stale. We recommend removing this file.';
$string['wheninfo'] = 'When. Action that provokes an event';
$string['wrongbehatsetup'] = 'Something is wrong with the behat setup and so step definitions cannot be listed: <b>{$a->errormsg}</b><br/><br/>Please check:<ul>
<li>$CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot are set in config.php with different values from $CFG->dataroot, $CFG->prefix and $CFG->wwwroot.</li>
+9 -10
View File
@@ -28,16 +28,15 @@ Feature: Verify that keyboard steps work as expected
And I press the shift tab key
And the focused element is "Username" "field"
# TODO: Uncomment the following when MDL-66979 is integrated.
# @javascript
# Scenario: Using the arrow keys allows me to navigate through menus
# Given the following "users" exist:
# | username | email | firstname | lastname |
# | saffronr | [email protected] | Saffron | Rutledge |
# And I log in as "saffronr"
# And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element"
# When I press the up key
# Then the focused element is "Log out" "link"
@javascript
Scenario: Using the arrow keys allows me to navigate through menus
Given the following "users" exist:
| username | email | firstname | lastname |
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge |
And I log in as "saffronr"
And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element"
When I press the up key
Then the focused element is "Log out" "link"
@javascript
Scenario: The escape key can be used to close a dialogue
@@ -14,8 +14,6 @@ Feature: Forms manipulation
Then the field "First name" matches value "Field value"
And the "Select a country" select box should contain "Japan"
And the field "New password" matches value "TestPass"
And I take focus off "Update profile" "button"
And I press "Update profile"
@javascript
Scenario: Expand all fieldsets and advanced elements
+1 -1
View File
@@ -7,7 +7,7 @@ default:
Behat\MinkExtension:
base_url: 'http://localhost:8000'
goutte: null
selenium2: null
webdriver: null
Moodle\BehatExtension:
moodledirroot: /Should/Change/To/Moodle/www/dir
steps_definitions: { }
@@ -46,49 +46,46 @@ Feature: View structural changes in recent activity block
| GG3 | G2 |
Scenario: Check that Added module information is displayed respecting view capability
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add the "Recent activity" block
When I add a "Forum" to section "1" and I fill the form with:
| name | ForumVisibleGroups |
| Description | No description |
| groupmode | Visible groups |
And I add a "Forum" to section "1" and I fill the form with:
| name | ForumSeparateGroups |
| Description | No description |
| groupmode | Separate groups |
And I add a "Forum" to section "1" and I fill the form with:
| name | ForumHidden |
| Description | No description |
| Availability | 0 |
And I add a "Forum" to section "1" and I fill the form with:
| name | ForumNoGroups |
| Description | No description |
| groupmode | No groups |
And I add a "Forum" to section "2" and I fill the form with:
| name | ForumVisibleGroupsG1 |
| Description | No description |
| groupmode | Visible groups |
| Grouping | Grouping 1 |
Given the following "activities" exist:
| activity | course | section | name | idnumber | description | groupmode | grouping | visible |
| forum | C1 | 1 | ForumVisibleGroups | forum1 | No description | 2 | | 1 |
| forum | C1 | 1 | ForumSeparateGroups | forum2 | No description | 1 | | 1 |
| forum | C1 | 1 | ForumHidden | forum3 | No description | 1 | | 0 |
| forum | C1 | 1 | ForumNoGroups | forum4 | No description | 0 | | 1 |
| forum | C1 | 2 | ForumVisibleGroupsG1 | forum5 | No description | 2 | GG1 | 1 |
| forum | C1 | 2 | ForumSeparateGroupsG1 | forum6 | No description | 1 | GG1 | 1 |
| forum | C1 | 3 | ForumVisibleGroupsG2 | forum7 | No description | 2 | GG2 | 1 |
| forum | C1 | 3 | ForumSeparateGroupsG2 | forum8 | No description | 1 | GG2 | 1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I click on "ForumVisibleGroupsG1" "link"
And I click on "Edit settings" "link"
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 1 |
And I add a "Forum" to section "2" and I fill the form with:
| name | ForumSeparateGroupsG1 |
| Description | No description |
| groupmode | Separate groups |
| Grouping | Grouping 1 |
| Access restrictions | Grouping: Grouping 1 |
And I add a "Forum" to section "3" and I fill the form with:
| name | ForumVisibleGroupsG2 |
| Description | No description |
| groupmode | Visible groups |
| Grouping | Grouping 2 |
And I press "Save and return to course"
And I click on "ForumSeparateGroupsG1" "link"
And I click on "Edit settings" "link"
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 1 |
And I press "Save and return to course"
And I click on "ForumVisibleGroupsG2" "link"
And I click on "Edit settings" "link"
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 2 |
And I add a "Forum" to section "3" and I fill the form with:
| name | ForumSeparateGroupsG2 |
| Description | No description |
| groupmode | Separate groups |
| Grouping | Grouping 2 |
| Access restrictions | Grouping: Grouping 2 |
And I press "Save and return to course"
And I click on "ForumSeparateGroupsG2" "link"
And I click on "Edit settings" "link"
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 2 |
And I press "Save and return to course"
And I am on "Course 1" course homepage with editing mode on
When I add the "Recent activity" block
Then I should see "ForumVisibleGroups" in the "Recent activity" "block"
And I should see "ForumSeparateGroups" in the "Recent activity" "block"
And I should see "ForumNoGroups" in the "Recent activity" "block"
@@ -98,6 +95,7 @@ Feature: View structural changes in recent activity block
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I log out
And I log in as "student1"
And I am on "Course 1" course homepage
And I should see "ForumVisibleGroups" in the "Recent activity" "block"
@@ -109,6 +107,7 @@ Feature: View structural changes in recent activity block
And I should not see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should not see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I log out
And I log in as "student2"
And I am on "Course 1" course homepage
And I should see "ForumVisibleGroups" in the "Recent activity" "block"
@@ -120,6 +119,7 @@ Feature: View structural changes in recent activity block
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I log out
And I log in as "student3"
And I am on "Course 1" course homepage
And I should see "ForumVisibleGroups" in the "Recent activity" "block"
@@ -131,6 +131,7 @@ Feature: View structural changes in recent activity block
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I log out
# Teachers have capability to see all groups and hidden activities
And I log in as "assistant1"
And I am on "Course 1" course homepage
@@ -142,15 +143,20 @@ Feature: View structural changes in recent activity block
And I log out
Scenario: Updates and deletes in recent activity block
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | ForumNew |
| description | No description |
When I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add the "Recent activity" block
And I add a "Forum" to section "1" and I fill the form with:
| name | ForumNew |
| Description | No description |
Then I should see "Added Forum" in the "Recent activity" "block"
And I should see "ForumNew" in the "Recent activity" "block"
And I log out
# Update forum as a teacher after a second to ensure we have a new timestamp for recent activity.
And I wait "1" seconds
And I log in as "student1"
And I am on "Course 1" course homepage
@@ -159,6 +165,7 @@ Feature: View structural changes in recent activity block
And I log out
# Update forum as a teacher after a second to ensure we have a new timestamp for recent activity.
And I wait "1" seconds
# Update forum as a teacher
And I log in as "teacher1"
And I am on "Course 1" course homepage
@@ -170,6 +177,7 @@ Feature: View structural changes in recent activity block
And I log out
And I wait "1" seconds
# Student 1 already saw that forum was created, now he can see that forum was updated
And I log in as "student1"
And I am on "Course 1" course homepage
And I should not see "Added Forum" in the "Recent activity" "block"
@@ -179,6 +187,7 @@ Feature: View structural changes in recent activity block
And I log out
And I wait "1" seconds
# Student 2 has bigger interval and he can see one entry that forum was created but with the new name
And I log in as "student2"
And I am on "Course 1" course homepage
And I should see "Added Forum" in the "Recent activity" "block"
@@ -188,6 +197,7 @@ Feature: View structural changes in recent activity block
And I log out
And I wait "1" seconds
# Delete forum as a teacher
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I delete "ForumUpdated" activity
@@ -195,6 +205,7 @@ Feature: View structural changes in recent activity block
And I log out
And I wait "1" seconds
# Students 1 and 2 see that forum was deleted
And I log in as "student1"
And I am on "Course 1" course homepage
And I should not see "Added Forum" in the "Recent activity" "block"
@@ -205,6 +216,7 @@ Feature: View structural changes in recent activity block
And I log out
And I wait "1" seconds
# Student 3 never knew that forum was created, so he does not see anything
And I log in as "student3"
And I am on "Course 1" course homepage
And I should not see "Added Forum" in the "Recent activity" "block"
@@ -212,4 +224,3 @@ Feature: View structural changes in recent activity block
And I should not see "Updated Forum" in the "Recent activity" "block"
And I should not see "ForumUpdated" in the "Recent activity" "block"
And I should not see "Deleted Forum" in the "Recent activity" "block"
And I log out
+5 -10
View File
@@ -4,16 +4,11 @@
"description": "Moodle - the world's open source learning platform",
"type": "project",
"homepage": "https://moodle.org",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/moodlehq/php-webdriver.git"
}
],
"require-dev": {
"phpunit/phpunit": "8.5.*",
"moodlehq/behat-extension": "3.310.0",
"mikey179/vfsstream": "^1.6",
"instaclick/php-webdriver": "dev-local as 1.x-dev"
}
"moodlehq/behat-extension": "3.310.2",
"mikey179/vfsstream": "^1.6"
},
"minimum-stability": "dev",
"prefer-stable": true
}
Generated
+759 -585
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -66,7 +66,7 @@ class behat_enrol extends behat_base {
// Ensure we get button in focus, before pressing button.
if ($this->running_javascript()) {
$this->execute("behat_general::i_take_focus_off_field", array(get_string('addinstance', 'enrol'), "button"));
$this->execute('behat_general::i_press_named_key', ['', 'tab']);
}
// Save changes.
@@ -65,6 +65,8 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe
And I click on student "Student 3" for grade item "Item SU"
And I set the field "ajaxgrade" to "Very good"
And I press the shift tab key
And I press the tab key
And I press the shift tab key
And I click on student "Student 3" for grade item "Item VU"
And I set the field "ajaxgrade" to "50"
And I press the enter key
+8 -36
View File
@@ -48,48 +48,20 @@ class behat_groups extends behat_base {
* @param string $groupname
*/
public function i_add_user_to_group_members($userfullname, $groupname) {
// Select the group in the select.
$this->execute('behat_forms::i_set_the_field_to', [get_string('groups', 'core'), $this->escape($groupname)]);
$userfullname = behat_context_helper::escape($userfullname);
// Press "Add/remove users".
$this->execute('behat_general::i_click_on', [get_string('adduserstogroup', 'group'), "button"]);
// Using a xpath liternal to avoid problems with quotes and double quotes.
$groupname = behat_context_helper::escape($groupname);
// We don't know the option text as it contains the number of users in the group.
$select = $this->find_field('groups');
$xpath = "//select[@id='groups']/descendant::option[contains(., $groupname)]";
$groupoption = $this->find('xpath', $xpath);
$fulloption = $groupoption->getText();
$select->selectOption($fulloption);
// This is needed by some drivers to ensure relevant event is triggred and button is enabled.
$driver = $this->getSession()->getDriver();
if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) {
$script = "Syn.trigger('change', {}, {{ELEMENT}})";
$driver->triggerSynScript($select->getXpath(), $script);
}
$this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS);
// Here we don't need to wait for the AJAX response.
$this->find_button(get_string('adduserstogroup', 'group'))->click();
// Wait for add/remove members page to be loaded.
$this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS);
// Getting the option and selecting it.
$select = $this->find_field('addselect');
$xpath = "//select[@id='addselect']/descendant::option[contains(., $userfullname)]";
$memberoption = $this->find('xpath', $xpath);
$fulloption = $memberoption->getText();
$select->selectOption($fulloption);
// Select the user.
$this->execute('behat_forms::i_set_the_field_to', ["addselect", $this->escape($userfullname)]);
// Click add button.
$this->find_button(get_string('add'))->click();
// Wait for the page to load.
$this->getSession()->wait(self::get_timeout() * 1000, self::PAGE_READY_JS);
$this->execute('behat_general::i_click_on', [get_string('add', 'core'), "button"]);
// Returning to the main groups page.
$this->find_button(get_string('backtogroups', 'group'))->click();
$this->execute('behat_general::i_click_on', [get_string('backtogroups', 'group'), "button"]);
}
/**
+5 -1
View File
@@ -179,7 +179,11 @@ class behat_command {
}
// Behat test command.
list($output, $code) = self::run(' --help');
$dirrootconfigpath = $CFG->dirroot . DIRECTORY_SEPARATOR . 'behat.yml';
if (file_exists($dirrootconfigpath)) {
self::output_msg(get_string('warndirrootconfigfound', 'tool_behat', $dirrootconfigpath));
}
list($output, $code) = self::run(" --help");
if ($code != 0) {
+62 -23
View File
@@ -475,12 +475,12 @@ class behat_config_util {
$parallelruns = $this->get_number_of_parallel_run();
}
$selenium2wdhost = array('wd_host' => 'http://localhost:4444/wd/hub');
$webdriverwdhost = array('wd_host' => 'http://localhost:4444/wd/hub');
// If parallel run, then set wd_host if specified.
if (!empty($currentrun) && !empty($parallelruns)) {
// Set proper selenium2 wd_host if defined.
// Set proper webdriver wd_host if defined.
if (!empty($CFG->behat_parallel_run[$currentrun - 1]['wd_host'])) {
$selenium2wdhost = array('wd_host' => $CFG->behat_parallel_run[$currentrun - 1]['wd_host']);
$webdriverwdhost = array('wd_host' => $CFG->behat_parallel_run[$currentrun - 1]['wd_host']);
}
}
@@ -525,7 +525,7 @@ class behat_config_util {
'Behat\MinkExtension' => array(
'base_url' => $CFG->behat_wwwroot,
'goutte' => null,
'selenium2' => $selenium2wdhost
'webdriver' => $webdriverwdhost
),
'Moodle\BehatExtension' => array(
'moodledirroot' => $CFG->dirroot,
@@ -634,20 +634,21 @@ class behat_config_util {
// We also need to disable web security, otherwise it can't make CSS requests to the server
// on localhost due to CORS restrictions.
if (!empty($values['browser']) && $values['browser'] === 'chrome') {
if (!isset($values['capabilities'])) {
$values['capabilities'] = [];
}
if (!isset($values['capabilities']['extra_capabilities'])) {
$values['capabilities']['extra_capabilities'] = [];
}
if (!isset($values['capabilities']['extra_capabilities']['chromeOptions'])) {
$values['capabilities']['extra_capabilities']['chromeOptions'] = [];
}
if (!isset($values['capabilities']['extra_capabilities']['chromeOptions']['args'])) {
$values['capabilities']['extra_capabilities']['chromeOptions']['args'] = [];
}
$values['capabilities']['extra_capabilities']['chromeOptions']['args'][] = '--unlimited-storage';
$values['capabilities']['extra_capabilities']['chromeOptions']['args'][] = '--disable-web-security';
$values = array_merge_recursive(
[
'capabilities' => [
'extra_capabilities' => [
'chromeOptions' => [
'args' => [
'unlimited-storage',
'disable-web-security',
],
],
],
],
],
$values
);
// If the mobile app is enabled, check its version and add appropriate tags.
if ($mobiletags = $this->get_mobile_version_tags()) {
@@ -657,6 +658,14 @@ class behat_config_util {
$values['tags'] = $mobiletags;
}
}
$values['capabilities']['extra_capabilities']['chromeOptions']['args'] = array_map(function($arg): string {
if (substr($arg, 0, 2) === '--') {
return substr($arg, 2);
}
return $arg;
}, $values['capabilities']['extra_capabilities']['chromeOptions']['args']);
sort($values['capabilities']['extra_capabilities']['chromeOptions']['args']);
}
// Fill tags information.
@@ -688,7 +697,7 @@ class behat_config_util {
$behatprofileextension = array(
'extensions' => array(
'Behat\MinkExtension' => array(
'selenium2' => $seleniumconfig,
'webdriver' => $seleniumconfig,
)
)
);
@@ -922,6 +931,7 @@ class behat_config_util {
// In case user defined overrides respect them over our default ones.
if (!empty($CFG->behat_config)) {
foreach ($CFG->behat_config as $profile => $values) {
$values = $this->fix_legacy_profile_data($profile, $values);
$config = $this->merge_config($config, $this->get_behat_config_for_profile($profile, $values));
}
}
@@ -948,11 +958,11 @@ class behat_config_util {
$oldconfigvalues = array();
if (isset($values['extensions']['Behat\MinkExtension\Extension'])) {
$extensionvalues = $values['extensions']['Behat\MinkExtension\Extension'];
if (isset($extensionvalues['selenium2']['browser'])) {
$oldconfigvalues['browser'] = $extensionvalues['selenium2']['browser'];
if (isset($extensionvalues['webdriver']['browser'])) {
$oldconfigvalues['browser'] = $extensionvalues['webdriver']['browser'];
}
if (isset($extensionvalues['selenium2']['wd_host'])) {
$oldconfigvalues['wd_host'] = $extensionvalues['selenium2']['wd_host'];
if (isset($extensionvalues['webdriver']['wd_host'])) {
$oldconfigvalues['wd_host'] = $extensionvalues['webdriver']['wd_host'];
}
if (isset($extensionvalues['capabilities'])) {
$oldconfigvalues['capabilities'] = $extensionvalues['capabilities'];
@@ -991,6 +1001,35 @@ class behat_config_util {
return $config;
}
/**
* Check for and attempt to fix legacy profile data.
*
* The Mink Driver used for W3C no longer uses the `selenium2` naming but otherwise is backwards compatibly.
*
* Emit a warning that users should update their configuration.
*
* @param string $profilename The name of this profile
* @param array $data The profile data for this profile
* @return array Th eamended profile data
*/
protected function fix_legacy_profile_data(string $profilename, array $data): array {
// Check for legacy instaclick profiles.
if (!array_key_exists('Behat\MinkExtension', $data['extensions'])) {
return $data;
}
if (array_key_exists('selenium2', $data['extensions']['Behat\MinkExtension'])) {
echo("\n\n");
echo("=> Warning: Legacy selenium2 profileuration was found for {$profilename} profile.\n");
echo("=> This has been renamed from 'selenium2' to 'webdriver'.\n");
echo("=> You should update your Behat configuration.\n");
echo("\n");
$data['extensions']['Behat\MinkExtension']['webdriver'] = $data['extensions']['Behat\MinkExtension']['selenium2'];
unset($data['extensions']['Behat\MinkExtension']['selenium2']);
}
return $data;
}
/**
* Cleans the path returned by get_components_with_tests() to standarize it
*
+62 -16
View File
@@ -23,21 +23,24 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Element\Element;
use Behat\Mink\Exception\DriverException;
use Behat\Mink\Exception\ExpectationException;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Element\Element;
use Behat\Mink\Exception\NoSuchWindowException;
use Behat\Mink\Session;
use Facebook\WebDriver\Exception\ScriptTimeoutException;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverElement;
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/component_named_replacement.php');
require_once(__DIR__ . '/component_named_selector.php');
// Alias the WebDriver\Key class to behat_keys to make future transition to a different WebDriver implementation
// easier.
class_alias('WebDriver\\Key', 'behat_keys');
// Alias the Facebook\WebDriver\WebDriverKeys class to behat_keys for better b/c with the older Instaclick driver.
class_alias('Facebook\WebDriver\WebDriverKeys', 'behat_keys');
/**
* A trait containing functionality used by the behat base context, and form fields.
@@ -253,9 +256,7 @@ trait behat_session_trait {
* @param string[] $keys
*/
public static function type_keys(Session $session, array $keys): void {
$session->getDriver()->getWebDriverSession()->keys([
'value' => $keys,
]);
$session->getDriver()->getWebDriver()->getKeyboard()->sendKeys($keys);
}
/**
@@ -833,7 +834,7 @@ EOF;
return M.util.pending_js.join(":");
})()'));
$pending = self::evaluate_script_in_session($session, $jscode);
} catch (NoSuchWindow $nsw) {
} catch (NoSuchWindowException $nsw) {
// We catch an exception here, in case we just closed the window we were interacting with.
// No javascript is running if there is no window right?
$pending = '';
@@ -973,7 +974,7 @@ EOF;
}
}
} catch (NoSuchWindow $e) {
} catch (NoSuchWindowException $e) {
// If we were interacting with a popup window it will not exists after closing it.
} catch (DriverException $e) {
// Same reason as above.
@@ -1079,17 +1080,62 @@ EOF;
if (!$this->running_javascript()) {
$node->click();
}
$this->ensure_node_is_visible($node); // Ensures hidden elements can't be clicked.
$xpath = $node->getXpath();
$driver = $this->getSession()->getDriver();
if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) {
$script = "Syn.click({{ELEMENT}})";
$driver->triggerSynScript($xpath, $script);
if ($driver instanceof \Moodle\BehatExtension\Driver\WebDriver) {
$this->execute_js_on_node($node, '{{ELEMENT}}.click();');
} else {
$driver->click($xpath);
$this->ensure_node_is_visible($node); // Ensures hidden elements can't be clicked.
$driver->click($node->getXpath());
}
}
/**
* Execute JS on the specified NodeElement.
*
* @param NodeElement $node
* @param string $script
* @param bool $async
*/
protected function execute_js_on_node(NodeElement $node, string $script, bool $async = false): void {
$driver = $this->getSession()->getDriver();
if (!($driver instanceof \Moodle\BehatExtension\Driver\WebDriver)) {
throw new \coding_exception('Unknown driver');
}
if (preg_match('/^function[\s\(]/', $script)) {
$script = preg_replace('/;$/', '', $script);
$script = '(' . $script . ')';
}
$script = str_replace('{{ELEMENT}}', 'arguments[0]', $script);
$webdriver = $driver->getWebDriver();
$element = $this->get_webdriver_element_from_node_element($node);
if ($async) {
try {
$webdriver->executeAsyncScript($script, [$element]);
} catch (ScriptTimeoutException $e) {
throw new DriverException($e->getMessage(), $e->getCode(), $e);
}
} else {
$webdriver->executeScript($script, [$element]);
}
}
/**
* Translate a Mink NodeElement into a WebDriver Element.
*
* @param NodeElement $node
* @return WebDriverElement
*/
protected function get_webdriver_element_from_node_element(NodeElement $node): WebDriverElement {
return $this->getSession()
->getDriver()
->getWebDriver()
->findElement(WebDriverBy::xpath($node->getXpath()));
}
/**
* Convert page names to URLs for steps like 'When I am on the "[page name]" page'.
*
+1 -1
View File
@@ -235,7 +235,7 @@ XPATH
.//descendant::input[@id = //label[contains(normalize-space(string(.)), %locator%)]/@for]/ancestor::*[@data-fieldtype = 'autocomplete']
XPATH
, 'iframe' => <<<XPATH
.//iframe[contains(concat(' ', normalize-space(@class), ' '), %locator% )]
.//iframe[(%idOrNameMatch% or (contains(concat(' ', normalize-space(@class), ' '), %locator% )))]
XPATH
);
@@ -25,7 +25,7 @@
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/behat_form_field.php');
require_once(__DIR__ . '/behat_form_textarea.php');
/**
* Availability form field class.
@@ -57,9 +57,6 @@ class behat_form_checkbox extends behat_form_field {
// Check it if it should be checked and it is not.
$this->field->click();
// Trigger the onchange event as triggered when 'checking' the checkbox.
$this->trigger_on_change();
} else if (empty($value) && $this->field->isChecked()) {
if (!$this->running_javascript()) {
@@ -69,9 +66,6 @@ class behat_form_checkbox extends behat_form_field {
// Uncheck if it is checked and shouldn't.
$this->field->click();
// Trigger the onchange event as triggered when 'checking' the checkbox.
$this->trigger_on_change();
}
}
@@ -103,17 +97,4 @@ class behat_form_checkbox extends behat_form_field {
return false;
}
/**
* Trigger on change event.
*/
protected function trigger_on_change() {
$driver = $this->session->getDriver();
if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) {
$driver->triggerSynScript(
$this->field->getXPath(),
"Syn.trigger('change', {}, {{ELEMENT}})"
);
}
}
}
+5 -2
View File
@@ -218,12 +218,15 @@ class behat_form_field implements behat_session_interface {
* @return int
*/
protected function get_internal_field_id() {
if (!$this->running_javascript()) {
throw new coding_exception('You can only get an internal ID using the selenium driver.');
}
return $this->session->getDriver()->getWebDriverSession()->element('xpath', $this->field->getXPath())->getID();
return $this->getSession()
->getDriver()
->getWebDriver()
->findElement(WebDriverBy::xpath($node->getXpath()))
->getID();
}
/**
@@ -48,28 +48,21 @@ class behat_form_passwordunmask extends behat_form_text {
* @return void
*/
public function set_value($value) {
if ($this->running_javascript()) {
$id = $this->field->getAttribute('id');
$js = <<<JS
(function() {
require(["jquery"], function($) {
var wrapper = $(document.getElementById("{$id}")).closest('[data-passwordunmask="wrapper"]');
wrapper.find('[data-passwordunmask="edit"]').trigger("click");
});
})();
JS;
behat_base::execute_script_in_session($this->session, $js);
if (!$this->running_javascript()) {
$this->field->setValue($value);
return;
}
$this->field->setValue($value);
$id = $this->field->getAttribute('id');
$wrapper = $this->field->getParent()->getParent()->find('css', '[data-passwordunmask="wrapper"]');
$wrapper->click();
$this->wait_for_pending_js();
// Ensure all pending JS is finished.
if ($this->running_javascript()) {
// Press enter key after setting password, so we have a stable page.
$this->field->keyDown(13);
$this->field->keyPress(13);
$this->field->keyUp(13);
$this->session->wait(behat_base::get_timeout() * 1000, behat_base::PAGE_READY_JS);
}
behat_base::type_keys($this->session, str_split($value));
$this->wait_for_pending_js();
// Press enter key after setting password to save.
behat_base::type_keys($this->session, [behat_keys::ENTER]);
}
}
+1 -31
View File
@@ -51,7 +51,6 @@ class behat_form_select extends behat_form_field {
// Is the select multiple?
$multiple = $this->field->hasAttribute('multiple');
$singleselect = ($this->field->hasClass('singleselect') || $this->field->hasClass('urlselect'));
// Here we select the option(s).
if ($multiple) {
@@ -64,38 +63,9 @@ class behat_form_select extends behat_form_field {
$afterfirstoption = true;
}
} else {
// By default, assume the passed value is a non-multiple option.
// By default, assume the passed value is a non-multiple option.
$this->field->selectOption(trim($value));
}
// Wait for all the possible AJAX requests that have been
// already triggered by selectOption() to be finished.
if ($this->running_javascript()) {
// Trigger change event and click on first skip link, as some OS/browsers (Phantomjs, Mac-FF),
// don't close select option field and trigger event.
if (!$singleselect) {
$dialoguexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue-focused ')]";
if (!$node = $this->session->getDriver()->find($dialoguexpath)) {
$script = "Syn.trigger('change', {}, {{ELEMENT}})";
try {
$driver = $this->session->getDriver();
if ($driver instanceof \Moodle\BehatExtension\Driver\MoodleSelenium2Driver) {
$driver->triggerSynScript($this->field->getXpath(), $script);
}
$driver->click('//body//div[@class="skiplinks"]');
} catch (\Exception $e) {
return;
}
} else {
try {
$this->session->getDriver()->click($dialoguexpath);
} catch (\Exception $e) {
return;
}
}
}
$this->session->wait(behat_base::get_timeout() * 1000, behat_base::PAGE_READY_JS);
}
}
/**
+3 -1
View File
@@ -67,9 +67,11 @@ class behat_forms extends behat_base {
// Ensures the button is present, before pressing.
$buttonnode = $this->find_button($button);
$buttonnode->press();
$this->wait_for_pending_js();
$this->look_for_exceptions();
// Switch to main window.
$this->getSession()->switchToWindow(behat_general::MAIN_WINDOW_NAME);
$this->execute('behat_general::switch_to_the_main_window');
}
/**
+28 -50
View File
@@ -159,49 +159,30 @@ class behat_general extends behat_base {
* Switches to the specified iframe.
*
* @Given /^I switch to "(?P<iframe_name_string>(?:[^"]|\\")*)" iframe$/
* @param string $iframename
*/
public function switch_to_iframe($iframename) {
// We spin to give time to the iframe to be loaded.
// Using extended timeout as we don't know about which
// kind of iframe will be loaded.
$this->spin(
function($context, $iframename) {
$context->getSession()->switchToIFrame($iframename);
// If no exception we are done.
return true;
},
$iframename,
behat_base::get_extended_timeout()
);
}
/**
* Switches to the iframe containing specified class.
*
* @Given /^I switch to "(?P<iframe_name_string>(?:[^"]|\\")*)" class iframe$/
* @param string $classname
* @param string $name The name of the iframe
*/
public function switch_to_class_iframe($classname) {
public function switch_to_iframe($name) {
// We spin to give time to the iframe to be loaded.
// Using extended timeout as we don't know about which
// kind of iframe will be loaded.
$this->spin(
function($context, $classname) {
$iframe = $this->find('iframe', $classname);
if (!empty($iframe->getAttribute('id'))) {
$iframename = $iframe->getAttribute('id');
} else {
function($context) use ($name){
$iframe = $context->find('iframe', $name);
if ($iframe->hasAttribute('name')) {
$iframename = $iframe->getAttribute('name');
} else {
if (!$this->running_javascript()) {
throw new \coding_exception('iframe must have a name attribute to use the switchTo command.');
}
$iframename = uniqid();
$this->execute_js_on_node($iframe, "{{ELEMENT}}.name = '{$iframename}';");
}
$context->getSession()->switchToIFrame($iframename);
// If no exception we are done.
return true;
},
$classname,
behat_base::get_extended_timeout()
);
}
@@ -222,13 +203,11 @@ class behat_general extends behat_base {
* @param string $windowname
*/
public function switch_to_window($windowname) {
// In Behat, some browsers (e.g. Chrome) are unable to switch to a
// window without a name, and by default the main browser window does
// not have a name. To work-around this, when we switch away from an
// unnamed window (presumably the main window) to some other named
// window, then we first set the main window name to a conventional
// value that we can later use this name to switch back.
$this->execute_script('if (window.name == "") window.name = "' . self::MAIN_WINDOW_NAME . '"');
if ($windowname === self::MAIN_WINDOW_NAME) {
// When switching to the main window normalise the window name to null.
// This is normalised further in the Mink driver to the root window ID.
$windowname = null;
}
$this->getSession()->switchToWindow($windowname);
}
@@ -239,7 +218,7 @@ class behat_general extends behat_base {
* @Given /^I switch to the main window$/
*/
public function switch_to_the_main_window() {
$this->getSession()->switchToWindow(self::MAIN_WINDOW_NAME);
$this->switch_to_window(self::MAIN_WINDOW_NAME);
}
/**
@@ -271,7 +250,7 @@ class behat_general extends behat_base {
* @Given /^I accept the currently displayed dialog$/
*/
public function accept_currently_displayed_alert_dialog() {
$this->getSession()->getDriver()->getWebDriverSession()->accept_alert();
$this->getSession()->getDriver()->getWebDriver()->switchTo()->alert()->accept();
}
/**
@@ -279,7 +258,7 @@ class behat_general extends behat_base {
* @Given /^I dismiss the currently displayed dialog$/
*/
public function dismiss_currently_displayed_alert_dialog() {
$this->getSession()->getDriver()->getWebDriverSession()->dismiss_alert();
$this->getSession()->getDriver()->getWebDriver()->switchTo()->alert()->dismiss();
}
/**
@@ -367,9 +346,9 @@ class behat_general extends behat_base {
* @param string $selectortype The type of what we look for
*/
public function i_hover($element, $selectortype) {
// Gets the node based on the requested selector type and locator.
$node = $this->get_selected_node($selectortype, $element);
$this->execute_js_on_node($node, '{{ELEMENT}}.scrollIntoView();');
$node->mouseOver();
}
@@ -418,7 +397,8 @@ class behat_general extends behat_base {
*/
public function i_click_on_confirming_the_dialogue($element, $selectortype) {
$this->i_click_on($element, $selectortype);
$this->accept_currently_displayed_alert_dialog();
$this->execute('behat_general::accept_currently_displayed_alert_dialog', []);
$this->wait_until_the_page_is_ready();
}
/**
@@ -431,7 +411,8 @@ class behat_general extends behat_base {
*/
public function i_click_on_dismissing_the_dialogue($element, $selectortype) {
$this->i_click_on($element, $selectortype);
$this->dismiss_currently_displayed_alert_dialog();
$this->execute('behat_general::dismiss_currently_displayed_alert_dialog', []);
$this->wait_until_the_page_is_ready();
}
/**
@@ -1802,16 +1783,16 @@ EOF;
$modifier = trim($key);
switch (strtoupper($key)) {
case 'UP':
$keys[] = behat_keys::UP_ARROW;
$keys[] = behat_keys::ARROW_UP;
break;
case 'DOWN':
$keys[] = behat_keys::DOWN_ARROW;
$keys[] = behat_keys::ARROW_DOWN;
break;
case 'LEFT':
$keys[] = behat_keys::LEFT_ARROW;
$keys[] = behat_keys::ARROW_LEFT;
break;
case 'RIGHT':
$keys[] = behat_keys::RIGHT_ARROW;
$keys[] = behat_keys::ARROW_RIGHT;
break;
case 'HOME':
$keys[] = behat_keys::HOME;
@@ -1852,9 +1833,6 @@ EOF;
throw new \coding_exception("Unknown key '$key'}");
}
// Always send the NULL key as the last key.
$keys[] = behat_keys::NULL_KEY;
behat_base::type_keys($this->getSession(), $keys);
}
+1 -1
View File
@@ -644,7 +644,7 @@ EOF;
// the following scenarios. Some browsers already closes the alert, so
// wrapping in a try & catch.
try {
$this->getSession()->getDriver()->getWebDriverSession()->accept_alert();
$this->getSession()->getDriver()->getWebDriver()->switchTo()->alert()->accept();
} catch (Exception $e) {
// Catching the generic one as we never know how drivers reacts here.
}
@@ -4,34 +4,39 @@ Feature: In an assignment, teachers can change filters in the grading app
As a teacher
I need to preserve filter settings between the grader app and grading table.
@javascript
Scenario: Set filters in the grading table and see them in the grading app
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| marker1 | Marker | 1 | marker1@example.com |
| marker2 | Marker | 2 | marker2@example.com |
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| marker1 | Marker | 1 | marker1@example.com |
| marker2 | Marker | 2 | marker2@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| marker1 | C1 | teacher |
| marker2 | C1 | teacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
| Assignment name | Test assignment name |
| Description | Submit your online text |
| assignsubmission_onlinetext_enabled | 1 |
| assignsubmission_file_enabled | 0 |
| Use marking workflow | Yes |
| Use marking allocation | Yes |
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| marker1 | C1 | teacher |
| marker2 | C1 | teacher |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment name |
| idnumber | assign |
| description | Submit your online text |
| assignsubmission_onlinetext_enabled | 1 |
| assignsubmission_file_enabled | 0 |
| markingworkflow | 1 |
| markingallocation | 1 |
@javascript
Scenario: Set filters in the grading table and see them in the grading app
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I follow "Test assignment name"
And I navigate to "View all submissions" in current page administration
And I click on "Grade" "link" in the "Student 1" "table_row"
@@ -55,32 +60,8 @@ Feature: In an assignment, teachers can change filters in the grading app
@javascript
Scenario: Set filters in the grading app and see them in the grading table
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| marker1 | Marker | 1 | marker1@example.com |
| marker2 | Marker | 2 | marker2@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| marker1 | C1 | teacher |
| marker2 | C1 | teacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
| Assignment name | Test assignment name |
| Description | Submit your online text |
| assignsubmission_onlinetext_enabled | 1 |
| assignsubmission_file_enabled | 0 |
| Use marking workflow | Yes |
| Use marking allocation | Yes |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I follow "Test assignment name"
And I navigate to "View all submissions" in current page administration
And I click on "Grade" "link" in the "Student 1" "table_row"
@@ -97,8 +78,6 @@ Feature: In an assignment, teachers can change filters in the grading app
And I click on "Grade" "link" in the "Student 1" "table_row"
And I click on "[data-region=user-filters]" "css_element"
And I set the field "filter" to "Not submitted"
# The popup closes for some reason, so it needs to be reopened.
And I click on "[data-region=user-filters]" "css_element"
And I set the field "markerfilter" to "Marker 1"
And I set the field "workflowfilter" to "In marking"
And I click on "View all submissions" "link"
@@ -165,9 +165,7 @@ class behat_mod_feedback extends behat_base {
// If chart data is not visible then expand.
$node = $this->get_selected_node("xpath_element", $charttabledataxpath);
if ($node) {
if (!$node->isVisible()) {
// Focus on node, before checking if it's visible.
$node->focus();
if ($node->getAttribute('aria-expanded') === 'false') {
$this->execute('behat_general::i_click_on_in_the', array(
get_string('showchartdata'),
'link',
@@ -15,15 +15,18 @@ Feature: A user can control their own subscription preferences for a discussion
| user | course | role |
| student1 | C1 | student |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
@javascript
Scenario: An optional forum can have discussions subscribed to
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Optional subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 0 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -62,11 +65,15 @@ Feature: A user can control their own subscription preferences for a discussion
@javascript
Scenario: An automatic subscription forum can have discussions unsubscribed from
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Auto subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 2 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -105,11 +112,15 @@ Feature: A user can control their own subscription preferences for a discussion
@javascript
Scenario: A user does not lose their preferences when a forum is switch from optional to automatic
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Optional subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 0 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -150,11 +161,15 @@ Feature: A user can control their own subscription preferences for a discussion
@javascript
Scenario: A user does not lose their preferences when a forum is switch from optional to automatic
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Optional subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 0 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -194,11 +209,15 @@ Feature: A user can control their own subscription preferences for a discussion
And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
Scenario: An optional forum prompts a user to subscribe to a discussion when posting unless they have already chosen not to subscribe
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Optional subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 0 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -230,11 +249,15 @@ Feature: A user can control their own subscription preferences for a discussion
And the field "Discussion subscription" matches value "I don't want to be notified of new posts in this discussion"
Scenario: An automatic forum prompts a user to subscribe to a discussion when posting unless they have already chosen not to subscribe
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Auto subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 2 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -267,6 +290,7 @@ Feature: A user can control their own subscription preferences for a discussion
Scenario: A guest should not be able to subscribe to a discussion
Given I am on site homepage
And I turn editing mode on
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
@@ -285,6 +309,7 @@ Feature: A user can control their own subscription preferences for a discussion
Scenario: A user who is not logged in should not be able to subscribe to a discussion
Given I am on site homepage
And I turn editing mode on
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
@@ -301,11 +326,15 @@ Feature: A user can control their own subscription preferences for a discussion
And "Unsubscribe from this discussion" "checkbox" should not exist
Scenario: A user can toggle their subscription preferences when viewing a discussion
Given I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name |
| Forum type | Standard forum for general use |
| Description | Test forum description |
| Subscription mode | Optional subscription |
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | Test forum name |
| intro | Test forum description |
| type | general |
| forcesubscribe | 0 |
And I am on "Course 1" course homepage
And I add a new discussion to "Test forum name" forum with:
| Subject | Test post subject one |
| Message | Test post message one |
@@ -15,6 +15,7 @@ Feature: Confirm progress gets saved on unload events
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And I change window size to "large"
@javascript
Scenario: Test progress gets saved correctly when the user navigates away from the scorm activity
@@ -27,16 +27,15 @@ Feature: Test creating a drag and drop markers question
And I set the field "Question text" to "Please place the markers on the map of Milton Keynes and be aware that there is more than one railway station."
And I set the field "General feedback" to "The Open University is at the junction of Brickhill Street and Groveway. There are three railway stations, Wolverton, Milton Keynes Central and Bletchley."
And I upload "question/type/ddmarker/tests/fixtures/mkmap.png" file to "Background image" filemanager
And I expand all fieldsets
# Markers.
And I follow "Markers"
And I set the field "id_drags_0_label" to "OU"
And I set the field "id_drags_0_noofdrags" to "1"
And I set the field "id_drags_1_label" to "Railway station"
And I set the field "id_drags_1_noofdrags" to "3"
# Drop zones.
And I follow "Drop zones"
And I set the field "id_drops_0_shape" to "Circle"
And I set the field "id_drops_0_coords" to "322,213;10"
And I set the field "id_drops_0_choice" to "1"
+7
View File
@@ -40,6 +40,13 @@ body.behat-site {
content: none;
}
}
// Workaround for MDL-70411.
// Pad the side of the message drawer out slightly to ensure that Firefox scroll bar does not cover controls at the
// edge of the screen.
[data-region="message-drawer"] {
padding-right: 10px;
}
}
.phpinfo table,
+3
View File
@@ -18769,6 +18769,9 @@ body.behat-site .custom-control-input {
body.behat-site .custom-control-label::before, body.behat-site .custom-control-label::after {
content: none; }
body.behat-site [data-region="message-drawer"] {
padding-right: 10px; }
.phpinfo table,
.phpinfo th,
.phpinfo h2 {
+3
View File
@@ -18950,6 +18950,9 @@ body.behat-site .custom-control-input {
body.behat-site .custom-control-label::before, body.behat-site .custom-control-label::after {
content: none; }
body.behat-site [data-region="message-drawer"] {
padding-right: 10px; }
.phpinfo table,
.phpinfo th,
.phpinfo h2 {
+9 -19
View File
@@ -17,19 +17,15 @@ Feature: Viewing the list of cohorts to enrol in a course
@javascript
Scenario: Check the teacher does not see the cohorts field without the proper capabilities
Given I log in as "admin"
Given the following "cohort" exists:
| name | Test cohort name |
| idnumber | 1337 |
| description | Test cohort description |
And I log in as "admin"
And I set the following system permissions of "Teacher" role:
| capability | permission |
| moodle/cohort:manage | Prohibit |
| moodle/cohort:view | Prohibit |
And I navigate to "Users > Accounts >Cohorts" in site administration
And I follow "Add new cohort"
And I set the following fields to these values:
| Name | Test cohort name |
| Context | System |
| Cohort ID | 1337 |
| Description | Test cohort description |
And I press "Save changes"
And I log out
And I log in as "teacher1"
And I am on "Course 1" course homepage
@@ -40,16 +36,10 @@ Feature: Viewing the list of cohorts to enrol in a course
@javascript
Scenario: Check we show the cohorts field if there are some present
Given I log in as "admin"
And I navigate to "Users > Accounts >Cohorts" in site administration
And I follow "Add new cohort"
And I set the following fields to these values:
| Name | Test cohort name |
| Context | System |
| Cohort ID | 1337 |
| Description | Test cohort description |
And I press "Save changes"
And I log out
Given the following "cohort" exists:
| name | Test cohort name |
| idnumber | 1337 |
| description | Test cohort description |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to course participants