Merge branch 'MDL-43738_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE
This commit is contained in:
@@ -90,10 +90,10 @@ Feature: Set up contextual data for tests
|
||||
And I expand "Users" node
|
||||
And I follow "Permissions"
|
||||
And I select "Student (1)" from "Advanced role override"
|
||||
Then the "mod/forum:editanypost" field should match "1" value
|
||||
Then "mod/forum:editanypost" capability has "Allow" permission
|
||||
And I press "Cancel"
|
||||
And I select "Teacher (1)" from "Advanced role override"
|
||||
And the "mod/forum:replynews" field should match "-1" value
|
||||
And "mod/forum:replynews" capability has "Prevent" permission
|
||||
And I press "Cancel"
|
||||
|
||||
Scenario: Add course enrolments
|
||||
|
||||
@@ -25,10 +25,10 @@ Feature: Edit capabilities
|
||||
| moodle/grade:managesharedforms | Prevent |
|
||||
| moodle/course:request | Prohibit |
|
||||
When I follow "Edit Teacher role"
|
||||
Then the "block/mnet_hosts:myaddinstance" field should match "1" value
|
||||
And the "moodle/community:add" field should match "0" value
|
||||
And the "moodle/grade:managesharedforms" field should match "-1" value
|
||||
And the "moodle/course:request" field should match "-1000" value
|
||||
Then "block/mnet_hosts:myaddinstance" capability has "Allow" permission
|
||||
And "moodle/community:add" capability has "Not set" permission
|
||||
And "moodle/grade:managesharedforms" capability has "Prevent" permission
|
||||
And "moodle/course:request" capability has "Prohibit" permission
|
||||
|
||||
@javascript
|
||||
Scenario: Course capabilities overrides
|
||||
@@ -41,9 +41,9 @@ Feature: Edit capabilities
|
||||
| mod/forum:editanypost | Prevent |
|
||||
| mod/forum:addquestion | Allow |
|
||||
When I select "Student (3)" from "Advanced role override"
|
||||
Then the "mod/forum:deleteanypost" field should match "-1000" value
|
||||
And the "mod/forum:editanypost" field should match "-1" value
|
||||
And the "mod/forum:addquestion" field should match "1" value
|
||||
Then "mod/forum:deleteanypost" capability has "Prohibit" permission
|
||||
And "mod/forum:editanypost" capability has "Prevent" permission
|
||||
And "mod/forum:addquestion" capability has "Allow" permission
|
||||
|
||||
@javascript
|
||||
Scenario: Module capabilities overrides
|
||||
@@ -60,6 +60,6 @@ Feature: Edit capabilities
|
||||
| mod/forum:editanypost | Prevent |
|
||||
| mod/forum:addquestion | Allow |
|
||||
When I select "Student (3)" from "Advanced role override"
|
||||
Then the "mod/forum:deleteanypost" field should match "-1000" value
|
||||
And the "mod/forum:editanypost" field should match "-1" value
|
||||
And the "mod/forum:addquestion" field should match "1" value
|
||||
Then "mod/forum:deleteanypost" capability has "Prohibit" permission
|
||||
And "mod/forum:editanypost" capability has "Prevent" permission
|
||||
And "mod/forum:addquestion" capability has "Allow" permission
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
@tool_behat
|
||||
Feature: Verify that all form fields values can be get and set
|
||||
In order to use behat steps definitions
|
||||
As a test writer
|
||||
I need to verify it all works in real moodle forms
|
||||
|
||||
Background:
|
||||
Given the following "courses" exists:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "users" exists:
|
||||
| username | email | firstname | lastname |
|
||||
| student1 | s1@asd.com | Student | 1 |
|
||||
| student2 | s2@asd.com | Student | 2 |
|
||||
| student3 | s3@asd.com | Student | 3 |
|
||||
And the following "course enrolments" exists:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
| student3 | C1 | student |
|
||||
| admin | C1 | editingteacher |
|
||||
And the following "groups" exists:
|
||||
| name | description | course | idnumber |
|
||||
| Group 1 | G1 description | C1 | G1 |
|
||||
| Group 2 | G1 description | C1 | G2 |
|
||||
And the following "group members" exists:
|
||||
| user | group |
|
||||
| student1 | G1 |
|
||||
| student2 | G1 |
|
||||
| student2 | G2 |
|
||||
| student3 | G2 |
|
||||
And the following "activities" exists:
|
||||
| activity | course | idnumber | name | intro | firstpagetitle | wikimode | visible |
|
||||
| wiki | C1 | wiki1 | Test this one | Test this one | Test this one | collaborative | 0 |
|
||||
And I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I expand "Appearance" node
|
||||
And I follow "Manage tags"
|
||||
# Select (multi-select) - We will check "I fill in...".
|
||||
And I fill in "otagsadd" with "OT1, OT2, OT3, OT4, OT5"
|
||||
And I press "Add official tags"
|
||||
And I am on homepage
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I follow "Test this one"
|
||||
And I press "Create page"
|
||||
# Select (multi-select) - Checking "the select box should contain".
|
||||
And the "tags[officialtags][]" select box should contain "OT1"
|
||||
And the "tags[officialtags][]" select box should contain "OT2"
|
||||
And the "tags[officialtags][]" select box should contain "OT3"
|
||||
And the "tags[officialtags][]" select box should contain "OT4"
|
||||
And the "tags[officialtags][]" select box should contain "OT5"
|
||||
And the "tags[officialtags][]" select box should contain "OT1, OT2, OT3, OT4, OT5"
|
||||
And the "tags[officialtags][]" select box should contain "OT5, OT4, OT3, OT2, OT1"
|
||||
And the "tags[officialtags][]" select box should not contain "OT6"
|
||||
And the "tags[officialtags][]" select box should not contain "OT7"
|
||||
And the "tags[officialtags][]" select box should not contain "OT6, OT7"
|
||||
# Text (textarea & editor) & Select (multi-select) - Checking "I fill the moodle form with".
|
||||
When I fill the moodle form with:
|
||||
| HTML format | Student page contents to be tagged |
|
||||
| tags[officialtags][] | OT1, OT3, OT5 |
|
||||
And I press "Save"
|
||||
Then I should see "Student page contents to be tagged" in the "region-main" "region"
|
||||
And I should see "OT1" in the ".wiki-tags" "css_element"
|
||||
And I should see "OT3" in the ".wiki-tags" "css_element"
|
||||
And I should see "OT5" in the ".wiki-tags" "css_element"
|
||||
And I should not see "OT2" in the ".wiki-tags" "css_element"
|
||||
And I should not see "OT4" in the ".wiki-tags" "css_element"
|
||||
And I follow "Edit"
|
||||
# Select (multi-select) - Checking "I select from".
|
||||
And I select "OT2, OT4" from "tags[officialtags][]"
|
||||
And I press "Save"
|
||||
And I should see "OT2" in the ".wiki-tags" "css_element"
|
||||
And I should see "OT4" in the ".wiki-tags" "css_element"
|
||||
And I should not see "OT1" in the ".wiki-tags" "css_element"
|
||||
And I should not see "OT3" in the ".wiki-tags" "css_element"
|
||||
And I should not see "OT5" in the ".wiki-tags" "css_element"
|
||||
And I follow "Edit"
|
||||
# Select (multi-select) - Checking "the field should match" and "the field does not match value".
|
||||
And the "tags[officialtags][]" field should match "OT2, OT4" value
|
||||
And the field "tags[officialtags][]" does not match value "OT4"
|
||||
And the field "tags[officialtags][]" does not match value "OT2"
|
||||
And the field "tags[officialtags][]" does not match value "OT1, OT3, OT5"
|
||||
And I press "Cancel"
|
||||
And I follow "Edit settings"
|
||||
And I expand all fieldsets
|
||||
# Checkbox - Checking "I check".
|
||||
And I check "Display description on course page"
|
||||
# Checkbox - Checking "I fill the moodle form with:".
|
||||
And I fill the moodle form with:
|
||||
| Force format | 1 |
|
||||
# Checkbox - Checking "the field should match" and "the field does not match value".
|
||||
And the "Display description on course page" field should match "1" value
|
||||
And the field "Display description on course page" does not match value ""
|
||||
And I press "Save and return to course"
|
||||
And I should see "Test this one"
|
||||
And I follow "Test this one"
|
||||
And I follow "Edit settings"
|
||||
# Checkbox - Checking "the field should match" and "the following fields match these values".
|
||||
And the following fields match these values:
|
||||
| Display description on course page | 1 |
|
||||
| Default format | HTML |
|
||||
| Wiki name | Test this one |
|
||||
And the "Force format" field should match "1" value
|
||||
# Select (simple) - Checking "I fill the moodle form with:".
|
||||
And I fill the moodle form with:
|
||||
| Default format | NWiki |
|
||||
| Display description on course page | |
|
||||
# Checkbox - Checking "I uncheck".
|
||||
And I uncheck "Force format"
|
||||
# Select (simple) - Checking "I select from".
|
||||
And I select "Separate groups" from "Group mode"
|
||||
And I press "Save and display"
|
||||
And I follow "Edit settings"
|
||||
And the following fields match these values:
|
||||
| Default format | NWiki |
|
||||
| Group mode | Separate groups |
|
||||
| Display description on course page | |
|
||||
| Force format | |
|
||||
# All fields - Checking "the following fields do not match these values".
|
||||
And the following fields do not match these values:
|
||||
| Wiki name | Test this one baby |
|
||||
| Default format | HTML |
|
||||
| Force format | 1 |
|
||||
And I press "Cancel"
|
||||
And I follow "Course 1"
|
||||
# Radio - Checking "I check" and "the field should match".
|
||||
And I add a "Choice" to section "1" and I fill the form with:
|
||||
| Choice name | Test choice name |
|
||||
| Description | Test choice description |
|
||||
| Allow choice to be updated | Yes |
|
||||
| Option 1 | one |
|
||||
| Option 2 | two |
|
||||
| Option 3 | three |
|
||||
And I follow "Test choice name"
|
||||
And I check "one"
|
||||
And I press "Save my choice"
|
||||
And the "one" field should match "1" value
|
||||
And the "two" field should match "" value
|
||||
|
||||
Scenario: with JS disabled all form fields getters and setters works as expected
|
||||
|
||||
@javascript
|
||||
Scenario: with JS enabled all form fields getters and setters works as expected
|
||||
Then I follow "Course 1"
|
||||
And I expand "Users" node
|
||||
And I follow "Groups"
|
||||
# Select (multi-select & AJAX) - Checking "I select from" and "select box should contain".
|
||||
And I select "Group 2" from "groups"
|
||||
And the "members" select box should contain "Student 2"
|
||||
And the "members" select box should contain "Student 3"
|
||||
And the "members" select box should not contain "Student 1"
|
||||
And I select "Group 1" from "groups"
|
||||
And the "members" select box should contain "Student 1"
|
||||
And the "members" select box should contain "Student 2"
|
||||
And the "members" select box should not contain "Student 3"
|
||||
# Checkbox (AJAX) - Checking "I check" and "I fill the moodle form with".
|
||||
And I follow "Course 1"
|
||||
And I add a "Lesson" to section "1"
|
||||
And I fill the moodle form with:
|
||||
| Name | Test lesson |
|
||||
| available[enabled] | 1 |
|
||||
And I check "deadline[enabled]"
|
||||
# Checkbox (AJAX) - Checking "field should match" before saving.
|
||||
And the "available[enabled]" field should match "1" value
|
||||
And the "available[day]" "field" should be enabled
|
||||
And the "deadline[enabled]" field should match "1" value
|
||||
And I press "Save and display"
|
||||
And I follow "Edit settings"
|
||||
And the "available[enabled]" field should match "1" value
|
||||
And the "available[day]" "field" should be enabled
|
||||
And the "deadline[enabled]" field should match "1" value
|
||||
And I press "Cancel"
|
||||
@@ -80,9 +80,16 @@ class behat_field_manager {
|
||||
|
||||
global $CFG;
|
||||
|
||||
// If the field is not part of a moodleform, we should still try to find out
|
||||
// which field type are we dealing with.
|
||||
if ($type == 'field' &&
|
||||
$guessedtype = self::guess_field_type($fieldnode, $session)) {
|
||||
$type = $guessedtype;
|
||||
}
|
||||
|
||||
$classname = 'behat_form_' . $type;
|
||||
|
||||
// Fallsback on the default form field if nothing specific exists.
|
||||
// Fallsback on the type guesser if nothing specific exists.
|
||||
$classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php';
|
||||
if (!file_exists($classpath)) {
|
||||
$classname = 'behat_form_field';
|
||||
@@ -94,6 +101,58 @@ class behat_field_manager {
|
||||
return new $classname($session, $fieldnode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses a basic field type and returns it.
|
||||
*
|
||||
* This method is intended to detect HTML form fields when no
|
||||
* moodleform-specific elements have been detected.
|
||||
*
|
||||
* @param NodeElement $fieldnode
|
||||
* @param Session $session
|
||||
* @return string|bool The field type or false.
|
||||
*/
|
||||
public static function guess_field_type(NodeElement $fieldnode, Session $session) {
|
||||
|
||||
// Textareas are considered text based elements.
|
||||
$tagname = strtolower($fieldnode->getTagName());
|
||||
if ($tagname == 'textarea') {
|
||||
|
||||
// If there is an iframe with $id + _ifr there a TinyMCE editor loaded.
|
||||
$xpath = '//iframe[@id="' . $fieldnode->getAttribute('id') . '_ifr"]';
|
||||
if ($session->getPage()->find('xpath', $xpath)) {
|
||||
return 'editor';
|
||||
}
|
||||
return 'textarea';
|
||||
|
||||
} else if ($tagname == 'input') {
|
||||
$type = $fieldnode->getAttribute('type');
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
case 'password':
|
||||
case 'email':
|
||||
case 'file':
|
||||
return 'text';
|
||||
case 'checkbox':
|
||||
return 'checkbox';
|
||||
break;
|
||||
case 'radio':
|
||||
return 'radio';
|
||||
break;
|
||||
default:
|
||||
// Here we return false because all text-based
|
||||
// fields should be included in the first switch case.
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ($tagname == 'select') {
|
||||
// Select tag.
|
||||
return 'select';
|
||||
}
|
||||
|
||||
// We can not provide a closer field type.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects when the field is a moodleform field type.
|
||||
*
|
||||
@@ -108,7 +167,10 @@ class behat_field_manager {
|
||||
protected static function is_moodleform_field(NodeElement $fieldnode) {
|
||||
|
||||
// We already waited when getting the NodeElement and we don't want an exception if it's not part of a moodleform.
|
||||
$parentformfound = $fieldnode->find('xpath', "/ancestor::form[contains(concat(' ', normalize-space(@class), ' '), ' mform ')]/fieldset");
|
||||
$parentformfound = $fieldnode->find('xpath',
|
||||
"/ancestor::fieldset" .
|
||||
"/ancestor::form[contains(concat(' ', normalize-space(@class), ' '), ' mform ')]"
|
||||
);
|
||||
|
||||
return ($parentformfound != false);
|
||||
}
|
||||
|
||||
@@ -47,18 +47,37 @@ class behat_form_checkbox extends behat_form_field {
|
||||
*/
|
||||
public function set_value($value) {
|
||||
|
||||
if (!$this->running_javascript()) {
|
||||
$this->field->check();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($value) && !$this->field->isChecked()) {
|
||||
|
||||
if (!$this->running_javascript()) {
|
||||
$this->field->check();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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->session->getDriver()->triggerSynScript(
|
||||
$this->field->getXPath(),
|
||||
"Syn.trigger('change', {}, {{ELEMENT}})"
|
||||
);
|
||||
|
||||
} else if (empty($value) && $this->field->isChecked()) {
|
||||
|
||||
if (!$this->running_javascript()) {
|
||||
$this->field->uncheck();
|
||||
return;
|
||||
}
|
||||
|
||||
// Uncheck if it is checked and shouldn't.
|
||||
$this->field->click();
|
||||
|
||||
// Trigger the onchange event as triggered when 'checking' the checkbox.
|
||||
$this->session->getDriver()->triggerSynScript(
|
||||
$this->field->getXPath(),
|
||||
"Syn.trigger('change', {}, {{ELEMENT}})"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,4 +89,25 @@ class behat_form_checkbox extends behat_form_field {
|
||||
public function get_value() {
|
||||
return $this->field->isChecked();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it enabled?
|
||||
*
|
||||
* @param string $expectedvalue Anything !empty() is considered checked.
|
||||
* @return bool
|
||||
*/
|
||||
public function matches($expectedvalue = false) {
|
||||
|
||||
$ischecked = $this->field->isChecked();
|
||||
|
||||
// Any non-empty value provided means that it should be checked.
|
||||
if (!empty($expectedvalue) && $ischecked) {
|
||||
return true;
|
||||
} else if (empty($expectedvalue) && !$ischecked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,15 +25,11 @@
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/behat_form_select.php');
|
||||
require_once(__DIR__ . '/behat_form_group.php');
|
||||
|
||||
/**
|
||||
* Date form field.
|
||||
*
|
||||
* Simple extension of behat_form_select to allow date-type
|
||||
* select fields to be filled like select elements instead of
|
||||
* text elements.
|
||||
*
|
||||
* This class will be refactored in case we are interested in
|
||||
* creating more complex formats to fill date and date-time fields.
|
||||
*
|
||||
@@ -42,4 +38,5 @@ require_once(__DIR__ . '/behat_form_select.php');
|
||||
* @copyright 2013 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_date_selector extends behat_form_select {}
|
||||
class behat_form_date_selector extends behat_form_group {
|
||||
}
|
||||
|
||||
@@ -25,21 +25,18 @@
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/behat_form_select.php');
|
||||
require_once(__DIR__ . '/behat_form_date_selector.php');
|
||||
|
||||
/**
|
||||
* Date time form field.
|
||||
*
|
||||
* Simple extension of behat_form_select to allow datetime-type
|
||||
* select fields to be filled like select elements instead of
|
||||
* text elements.
|
||||
*
|
||||
* This class will be refactored in case we are interested in
|
||||
* creating more complex formats to fill date and date-time fields.
|
||||
* creating more complex formats to fill date-time fields.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2013 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_date_time_selector extends behat_form_select {}
|
||||
class behat_form_date_time_selector extends behat_form_date_selector {
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
use Behat\Mink\Element\NodeElement as NodeElement;
|
||||
|
||||
require_once(__DIR__ . '/behat_form_field.php');
|
||||
require_once(__DIR__ . '/behat_form_textarea.php');
|
||||
|
||||
/**
|
||||
* Moodle editor field.
|
||||
@@ -38,7 +38,7 @@ require_once(__DIR__ . '/behat_form_field.php');
|
||||
* @copyright 2012 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_editor extends behat_form_field {
|
||||
class behat_form_editor extends behat_form_textarea {
|
||||
|
||||
/**
|
||||
* Sets the value to a field.
|
||||
|
||||
@@ -69,14 +69,11 @@ class behat_form_field {
|
||||
* @return void
|
||||
*/
|
||||
public function set_value($value) {
|
||||
|
||||
// If we are not dealing with a text-based tag try to find the most appropiate
|
||||
// behat_form_* class to deal with it.
|
||||
if ($instance = $this->guess_type()) {
|
||||
$instance->set_value($value);
|
||||
} else {
|
||||
$this->field->setValue($value);
|
||||
}
|
||||
// We delegate to the best guess, if we arrived here
|
||||
// using the generic behat_form_field is because we are
|
||||
// dealing with a fgroup element.
|
||||
$instance = $this->guess_type();
|
||||
return $instance->set_value($value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,14 +82,28 @@ class behat_form_field {
|
||||
* @return string
|
||||
*/
|
||||
public function get_value() {
|
||||
// We delegate to the best guess, if we arrived here
|
||||
// using the generic behat_form_field is because we are
|
||||
// dealing with a fgroup element.
|
||||
$instance = $this->guess_type();
|
||||
return $instance->get_value();
|
||||
}
|
||||
|
||||
// If we are not dealing with a text-based tag try to find the most appropiate
|
||||
// behat_form_* class to deal with it.
|
||||
if ($instance = $this->guess_type()) {
|
||||
return $instance->get_value();
|
||||
} else {
|
||||
return $this->field->getValue();
|
||||
}
|
||||
/**
|
||||
* Generic match implementation
|
||||
*
|
||||
* Will work well with text-based fields, extension required
|
||||
* for most of the other cases.
|
||||
*
|
||||
* @param string $expectedvalue
|
||||
* @return bool The provided value matches the field value?
|
||||
*/
|
||||
public function matches($expectedvalue) {
|
||||
// We delegate to the best guess, if we arrived here
|
||||
// using the generic behat_form_field is because we are
|
||||
// dealing with a fgroup element.
|
||||
$instance = $this->guess_type();
|
||||
return $instance->matches($expectedvalue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,53 +117,17 @@ class behat_form_field {
|
||||
* moodle form elements we will need to refactor this simple HTML elements
|
||||
* guess method.
|
||||
*
|
||||
* @return mixed False if no need for an special behat_form_*, otherwise the behat_form_*
|
||||
* @return behat_form_field
|
||||
*/
|
||||
private function guess_type() {
|
||||
global $CFG;
|
||||
|
||||
// Textareas are considered text based elements.
|
||||
$tagname = strtolower($this->field->getTagName());
|
||||
if ($tagname == 'textarea') {
|
||||
|
||||
if (!$this->running_javascript()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there is an iframe with $id + _ifr there a TinyMCE editor loaded.
|
||||
$xpath = '//iframe[@id="' . $this->field->getAttribute('id') . '_ifr"]';
|
||||
if (!$this->session->getPage()->find('xpath', $xpath)) {
|
||||
|
||||
// Generic one if it is a normal textarea.
|
||||
return false;
|
||||
}
|
||||
|
||||
$classname = 'behat_form_editor';
|
||||
|
||||
} else if ($tagname == 'input') {
|
||||
$type = $this->field->getAttribute('type');
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
return false;
|
||||
case 'checkbox':
|
||||
$classname = 'behat_form_checkbox';
|
||||
break;
|
||||
case 'radio':
|
||||
$classname = 'behat_form_radio';
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ($tagname == 'select') {
|
||||
// Select tag.
|
||||
$classname = 'behat_form_select';
|
||||
|
||||
} else {
|
||||
// We can not provide a closer field type.
|
||||
return false;
|
||||
// We default to the text-based field if nothing was detected.
|
||||
if (!$type = behat_field_manager::guess_field_type($this->field, $this->session)) {
|
||||
$type = 'text';
|
||||
}
|
||||
|
||||
$classname = 'behat_form_' . $type;
|
||||
$classpath = $CFG->dirroot . '/lib/behat/form_field/' . $classname . '.php';
|
||||
require_once($classpath);
|
||||
return new $classname($this->session, $this->field);
|
||||
@@ -181,10 +156,19 @@ class behat_form_field {
|
||||
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->session->getDriver()->getWebDriverSession()->element('xpath', $this->field->getXPath())->getID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided text matches the field value.
|
||||
*
|
||||
* @param string $expectedvalue
|
||||
* @return bool
|
||||
*/
|
||||
protected function text_matches($expectedvalue) {
|
||||
if (trim($expectedvalue) != trim($this->get_value())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Generic group field class.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2014 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/behat_form_field.php');
|
||||
|
||||
/**
|
||||
* Class to re-guess the field type as grouped fields can have different field types.
|
||||
*
|
||||
* When filling fields inside a fgroup field element we don't know what kind
|
||||
* of field are we dealing with, so we should re-guess it as behat_form_field
|
||||
* does.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2014 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_group extends behat_form_field {
|
||||
}
|
||||
@@ -38,4 +38,5 @@ require_once(__DIR__ . '/behat_form_select.php');
|
||||
* @copyright 2013 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_modvisible extends behat_form_select {}
|
||||
class behat_form_modvisible extends behat_form_select {
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ require_once(__DIR__ . '/behat_form_checkbox.php');
|
||||
* Radio input form field.
|
||||
*
|
||||
* Extends behat_form_checkbox as the set_value() behaviour
|
||||
* is the same.
|
||||
* is the same and it behaves closer to a checkbox than to
|
||||
* a text field.
|
||||
*
|
||||
* This form field type can be added to forms as any other
|
||||
* moodle form element, but it does not make sense without
|
||||
@@ -51,9 +52,43 @@ class behat_form_radio extends behat_form_checkbox {
|
||||
/**
|
||||
* Returns the radio input value attribute.
|
||||
*
|
||||
* Here we can not extend behat_form_checkbox because
|
||||
* isChecked() does internally a (bool)getValue() and
|
||||
* it is not good for radio buttons.
|
||||
*
|
||||
* @return string The value attribute
|
||||
*/
|
||||
public function get_value() {
|
||||
return $this->field->getValue();
|
||||
return (bool)$this->field->getAttribute('checked');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a radio
|
||||
*
|
||||
* Partially overwriting behat_form_checkbox
|
||||
* implementation as when JS is disabled we
|
||||
* can not check() and we should use setValue()
|
||||
*
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function set_value($value) {
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
parent::set_value($value);
|
||||
} else {
|
||||
// Goutte does not accept a check nor a click in an input[type=radio].
|
||||
$this->field->setValue($this->field->getAttribute('value'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the provided value matches the current value or not.
|
||||
*
|
||||
* @param string $expectedvalue
|
||||
* @return bool
|
||||
*/
|
||||
public function matches($expectedvalue = false) {
|
||||
return $this->text_matches($expectedvalue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@ require_once(__DIR__ . '/behat_form_field.php');
|
||||
class behat_form_select extends behat_form_field {
|
||||
|
||||
/**
|
||||
* Sets the value of a single select.
|
||||
* Sets the value(s) of a select element.
|
||||
*
|
||||
* Seems an easy select, but there are lots of combinations
|
||||
* of browsers and operative systems and each one manages the
|
||||
* autosubmits and the multiple option selects in a diferent way.
|
||||
* autosubmits and the multiple option selects in a different way.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $value plain value or comma separated values if multiple. Commas in values escaped with backslash.
|
||||
* @return void
|
||||
*/
|
||||
public function set_value($value) {
|
||||
@@ -61,8 +61,26 @@ class behat_form_select extends behat_form_field {
|
||||
$currentelementid = $this->get_internal_field_id();
|
||||
}
|
||||
|
||||
// Here we select an option.
|
||||
$this->field->selectOption($value);
|
||||
// Is the select multiple?
|
||||
$multiple = $this->field->hasAttribute('multiple');
|
||||
|
||||
// By default, assume the passed value is a non-multiple option.
|
||||
$options = array(trim($value));
|
||||
|
||||
// Here we select the option(s).
|
||||
if ($multiple) {
|
||||
// Split and decode values. Comma separated list of values allowed. With valuable commas escaped with backslash.
|
||||
$options = preg_replace('/\\\,/', ',', preg_split('/(?<!\\\),/', $value));
|
||||
// This is a multiple select, let's pass the multiple flag after first option.
|
||||
$afterfirstoption = false;
|
||||
foreach ($options as $option) {
|
||||
$this->field->selectOption(trim($option), $afterfirstoption);
|
||||
$afterfirstoption = true;
|
||||
}
|
||||
} else {
|
||||
// This is a single select, let's pass the last one specified.
|
||||
$this->field->selectOption(end($options));
|
||||
}
|
||||
|
||||
// With JS disabled this is enough and we finish here.
|
||||
if (!$this->running_javascript()) {
|
||||
@@ -75,6 +93,7 @@ class behat_form_select extends behat_form_field {
|
||||
// In some browsers the selectOption actions can perform a form submit or reload page
|
||||
// so we need to ensure the element is still available to continue interacting
|
||||
// with it. We don't wait here.
|
||||
// getXpath() does not send a query to selenium, so we don't need to wrap it in a try & catch.
|
||||
$selectxpath = $this->field->getXpath();
|
||||
if (!$this->session->getDriver()->find($selectxpath)) {
|
||||
return;
|
||||
@@ -87,12 +106,9 @@ class behat_form_select extends behat_form_field {
|
||||
return;
|
||||
}
|
||||
|
||||
// We also check that the option is still there. We neither wait.
|
||||
$valueliteral = $this->session->getSelectorsHandler()->xpathLiteral($value);
|
||||
$optionxpath = $selectxpath . "/descendant::option[(./@value=$valueliteral or normalize-space(.)=$valueliteral)]";
|
||||
if (!$this->session->getDriver()->find($optionxpath)) {
|
||||
return;
|
||||
}
|
||||
// Wait for all the possible AJAX requests that have been
|
||||
// already triggered by selectOption() to be finished.
|
||||
$this->session->wait(behat_base::TIMEOUT * 1000, behat_base::PAGE_READY_JS);
|
||||
|
||||
// Wrapped in try & catch as the element may disappear if an AJAX request was submitted.
|
||||
try {
|
||||
@@ -105,17 +121,16 @@ class behat_form_select extends behat_form_field {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for all the possible AJAX requests that have been
|
||||
// already triggered by selectOption() to be finished.
|
||||
$this->session->wait(behat_base::TIMEOUT * 1000, behat_base::PAGE_READY_JS);
|
||||
|
||||
// Single select sometimes needs an extra click in the option.
|
||||
if (!$multiple) {
|
||||
|
||||
// Var $options only contains 1 option.
|
||||
$optionxpath = $this->get_option_xpath(end($options), $selectxpath);
|
||||
|
||||
// Using the driver direcly because Element methods are messy when dealing
|
||||
// with elements inside containers.
|
||||
$optionnodes = $this->session->getDriver()->find($optionxpath);
|
||||
if ($optionnodes) {
|
||||
if ($optionnodes = $this->session->getDriver()->find($optionxpath)) {
|
||||
|
||||
// Wrapped in a try & catch as we can fall into race conditions
|
||||
// and the element may not be there.
|
||||
try {
|
||||
@@ -138,21 +153,29 @@ class behat_form_select extends behat_form_field {
|
||||
return;
|
||||
}
|
||||
|
||||
// We ensure that the option is still there.
|
||||
if (!$this->session->getDriver()->find($optionxpath)) {
|
||||
return;
|
||||
// We also check that the option(s) are still there. We neither wait.
|
||||
foreach ($options as $option) {
|
||||
$optionxpath = $this->get_option_xpath($option, $selectxpath);
|
||||
if (!$this->session->getDriver()->find($optionxpath)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all the possible AJAX requests that have been
|
||||
// already triggered by selectOption() to be finished.
|
||||
// already triggered by clicking on the field to be finished.
|
||||
$this->session->wait(behat_base::TIMEOUT * 1000, behat_base::PAGE_READY_JS);
|
||||
|
||||
// Wrapped in a try & catch as we can fall into race conditions
|
||||
// and the element may not be there.
|
||||
try {
|
||||
// Repeating the select as some drivers (chrome that I know) are moving
|
||||
|
||||
// Repeating the select(s) as some drivers (chrome that I know) are moving
|
||||
// to another option after the general select field click above.
|
||||
$this->field->selectOption($value);
|
||||
$afterfirstoption = false;
|
||||
foreach ($options as $option) {
|
||||
$this->field->selectOption(trim($option), $afterfirstoption);
|
||||
$afterfirstoption = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// We continue and return as this means that the element is not there or it is not the same.
|
||||
return;
|
||||
@@ -161,12 +184,165 @@ class behat_form_select extends behat_form_field {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text of the current value.
|
||||
* Returns the text of the currently selected options.
|
||||
*
|
||||
* @return string
|
||||
* @return string Comma separated if multiple options are selected. Commas in option texts escaped with backslash.
|
||||
*/
|
||||
public function get_value() {
|
||||
$selectedoption = $this->field->find('xpath', '//option[@selected="selected"]');
|
||||
return $selectedoption->getText();
|
||||
return $this->get_selected_options();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the provided argument matches the current value.
|
||||
*
|
||||
* @param mixed $expectedvalue
|
||||
* @return bool
|
||||
*/
|
||||
public function matches($expectedvalue) {
|
||||
|
||||
$multiple = $this->field->hasAttribute('multiple');
|
||||
|
||||
// Same implementation as the parent if it is a single select.
|
||||
if (!$multiple) {
|
||||
$cleanexpectedvalue = trim($expectedvalue);
|
||||
$selectedtext = trim($this->get_selected_options());
|
||||
$selectedvalue = trim($this->get_selected_options(false));
|
||||
if ($cleanexpectedvalue != $selectedvalue && $cleanexpectedvalue != $selectedtext) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// We are dealing with a multi-select.
|
||||
|
||||
// Can pass multiple comma separated, with valuable commas escaped with backslash.
|
||||
$expectedarr = array(); // Array of passed text options to test.
|
||||
|
||||
// Unescape + trim all options and flip it to have the expected values as keys.
|
||||
$expectedoptions = $this->get_unescaped_options($expectedvalue);
|
||||
|
||||
// Get currently selected option's texts.
|
||||
$texts = $this->get_selected_options(true);
|
||||
$selectedoptiontexts = $this->get_unescaped_options($texts);
|
||||
|
||||
// Get currently selected option's values.
|
||||
$values = $this->get_selected_options(false);
|
||||
$selectedoptionvalues = $this->get_unescaped_options($values);
|
||||
|
||||
// Precheck to speed things up.
|
||||
if (count($expectedoptions) !== count($selectedoptiontexts) ||
|
||||
count($expectedoptions) !== count($selectedoptionvalues)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We check against string-ordered lists of options.
|
||||
if ($expectedoptions != $selectedoptiontexts &&
|
||||
$expectedoptions != $selectedoptionvalues) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the list of options and returns it as a string separating options with |||.
|
||||
*
|
||||
* @param string $value The string containing the escaped options.
|
||||
* @return string The options
|
||||
*/
|
||||
protected function get_unescaped_options($value) {
|
||||
|
||||
// Can be multiple comma separated, with valuable commas escaped with backslash.
|
||||
$optionsarray = array_map(
|
||||
'trim',
|
||||
preg_replace('/\\\,/', ',',
|
||||
preg_split('/(?<!\\\),/', $value)
|
||||
)
|
||||
);
|
||||
|
||||
// Sort by value (keeping the keys is irrelevant).
|
||||
core_collator::asort($optionsarray, SORT_STRING);
|
||||
|
||||
// Returning it as a string which is easier to match against other values.
|
||||
return implode('|||', $optionsarray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field selected values.
|
||||
*
|
||||
* Externalized from the common behat_form_field API method get_value() as
|
||||
* matches() needs to check against both values and texts.
|
||||
*
|
||||
* @param bool $returntexts Returns the options texts or the options values.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_selected_options($returntexts = true) {
|
||||
|
||||
$method = 'getText';
|
||||
if ($returntexts === false) {
|
||||
$method = 'getValue';
|
||||
}
|
||||
|
||||
// Is the select multiple?
|
||||
$multiple = $this->field->hasAttribute('multiple');
|
||||
|
||||
$selectedoptions = array(); // To accumulate found selected options.
|
||||
|
||||
// Selenium getValue() implementation breaks - separates - values having
|
||||
// commas within them, so we'll be looking for options with the 'selected' attribute instead.
|
||||
if ($this->running_javascript()) {
|
||||
// Get all the options in the select and extract their value/text pairs.
|
||||
$alloptions = $this->field->findAll('xpath', '//option');
|
||||
foreach ($alloptions as $option) {
|
||||
// Is it selected?
|
||||
if ($option->hasAttribute('selected')) {
|
||||
if ($multiple) {
|
||||
// If the select is multiple, text commas must be encoded.
|
||||
$selectedoptions[] = trim(str_replace(',', '\,', $option->{$method}()));
|
||||
} else {
|
||||
$selectedoptions[] = trim($option->{$method}());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Goutte does not keep the 'selected' attribute updated, but its getValue() returns
|
||||
// the selected elements correctly, also those having commas within them.
|
||||
|
||||
// Goutte returns the values as an array or as a string depending
|
||||
// on whether multiple options are selected or not.
|
||||
$values = $this->field->getValue();
|
||||
if (!is_array($values)) {
|
||||
$values = array($values);
|
||||
}
|
||||
|
||||
// Get all the options in the select and extract their value/text pairs.
|
||||
$alloptions = $this->field->findAll('xpath', '//option');
|
||||
foreach ($alloptions as $option) {
|
||||
// Is it selected?
|
||||
if (in_array($option->getValue(), $values)) {
|
||||
if ($multiple) {
|
||||
// If the select is multiple, text commas must be encoded.
|
||||
$selectedoptions[] = trim(str_replace(',', '\,', $option->{$method}()));
|
||||
} else {
|
||||
$selectedoptions[] = trim($option->{$method}());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode(', ', $selectedoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the opton XPath based on it's select xpath.
|
||||
*
|
||||
* @param string $option
|
||||
* @param string $selectxpath
|
||||
* @return string xpath
|
||||
*/
|
||||
protected function get_option_xpath($option, $selectxpath) {
|
||||
$valueliteral = $this->session->getSelectorsHandler()->xpathLiteral(trim($option));
|
||||
return $selectxpath . "/descendant::option[(./@value=$valueliteral or normalize-space(.)=$valueliteral)]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,4 +38,5 @@ require_once(__DIR__ . '/behat_form_select.php');
|
||||
* @copyright 2013 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_selectyesno extends behat_form_select {}
|
||||
class behat_form_selectyesno extends behat_form_select {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Text field class.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2014 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/behat_form_field.php');
|
||||
|
||||
/**
|
||||
* Class for test-based fields.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2014 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_text extends behat_form_field {
|
||||
|
||||
/**
|
||||
* Sets the value to a field.
|
||||
*
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function set_value($value) {
|
||||
$this->field->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value of the element.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value() {
|
||||
return $this->field->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the provided value against the current field value.
|
||||
*
|
||||
* @param string $expectedvalue
|
||||
* @return bool The provided value matches the field value?
|
||||
*/
|
||||
public function matches($expectedvalue) {
|
||||
return $this->text_matches($expectedvalue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Textarea field class.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2014 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/behat_form_text.php');
|
||||
|
||||
/**
|
||||
* Textarea field class.
|
||||
*
|
||||
* @package core_form
|
||||
* @category test
|
||||
* @copyright 2014 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_form_textarea extends behat_form_text {
|
||||
}
|
||||
@@ -299,13 +299,13 @@ class behat_data_generators extends behat_base {
|
||||
$context = $this->get_context($data['contextlevel'], $data['reference']);
|
||||
|
||||
switch ($data['permission']) {
|
||||
case self::cap_allow:
|
||||
case get_string('allow', 'role'):
|
||||
$permission = CAP_ALLOW;
|
||||
break;
|
||||
case self::cap_prevent:
|
||||
case get_string('prevent', 'role'):
|
||||
$permission = CAP_PREVENT;
|
||||
break;
|
||||
case self::cap_prohibit:
|
||||
case get_string('prohibit', 'role'):
|
||||
$permission = CAP_PROHIBIT;
|
||||
break;
|
||||
default:
|
||||
|
||||
+223
-50
@@ -60,6 +60,29 @@ class behat_forms extends behat_base {
|
||||
$buttonnode->press();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a form with field/value data. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
|
||||
*
|
||||
* Backport of Moodle 2.7 method to help backporting
|
||||
* features to 2.6.
|
||||
*
|
||||
* @Given /^I set the following fields to these values:$/
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param TableNode $data
|
||||
*/
|
||||
public function i_set_the_following_fields_to_these_values(TableNode $data) {
|
||||
|
||||
// Expand all fields in case we have.
|
||||
$this->expand_all_fields();
|
||||
|
||||
$datahash = $data->getRowsHash();
|
||||
|
||||
// The action depends on the field type.
|
||||
foreach ($datahash as $locator => $value) {
|
||||
$this->set_field_value($locator, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a moodle form with field/value data.
|
||||
*
|
||||
@@ -154,7 +177,23 @@ class behat_forms extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in form field with specified id|name|label|value.
|
||||
* Sets the specified value to the field.
|
||||
*
|
||||
* Backport of Moodle 2.7 method to help backporting
|
||||
* features to 2.6.
|
||||
*
|
||||
* @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function i_set_the_field_to($field, $value) {
|
||||
$this->set_field_value($field, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in form text field with specified id|name|label|value. It works with text-based fields.
|
||||
*
|
||||
* @When /^I fill in "(?P<field_string>(?:[^"]|\\")*)" with "(?P<value_string>(?:[^"]|\\")*)"$/
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
@@ -162,9 +201,7 @@ class behat_forms extends behat_base {
|
||||
* @param string $value
|
||||
*/
|
||||
public function fill_field($field, $value) {
|
||||
|
||||
$fieldnode = $this->find_field($field);
|
||||
$fieldnode->setValue($value);
|
||||
$this->set_field_value($field, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,13 +213,7 @@ class behat_forms extends behat_base {
|
||||
* @param string $select
|
||||
*/
|
||||
public function select_option($option, $select) {
|
||||
|
||||
$selectnode = $this->find_field($select);
|
||||
|
||||
// We delegate to behat_form_field class, it will
|
||||
// guess the type properly as it is a select tag.
|
||||
$selectformfield = behat_field_manager::get_form_field($selectnode, $this->getSession());
|
||||
$selectformfield->set_value($option);
|
||||
$this->set_field_value($select, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,14 +224,7 @@ class behat_forms extends behat_base {
|
||||
* @param string $radio The radio button id, name or label value
|
||||
*/
|
||||
public function select_radio($radio) {
|
||||
|
||||
$radionode = $this->find_radio($radio);
|
||||
$radionode->check();
|
||||
|
||||
// Adding a click as Selenium requires it to fire some JS events.
|
||||
if ($this->running_javascript()) {
|
||||
$radionode->click();
|
||||
}
|
||||
$this->set_field_value($radio, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,11 +235,7 @@ class behat_forms extends behat_base {
|
||||
* @param string $option
|
||||
*/
|
||||
public function check_option($option) {
|
||||
|
||||
// We don't delegate to behat_form_checkbox as the
|
||||
// step is explicitly saying I check.
|
||||
$checkboxnode = $this->find_field($option);
|
||||
$checkboxnode->check();
|
||||
$this->set_field_value($option, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,15 +246,11 @@ class behat_forms extends behat_base {
|
||||
* @param string $option
|
||||
*/
|
||||
public function uncheck_option($option) {
|
||||
|
||||
// We don't delegate to behat_form_checkbox as the
|
||||
// step is explicitly saying I uncheck.
|
||||
$checkboxnode = $this->find_field($option);
|
||||
$checkboxnode->uncheck();
|
||||
$this->set_field_value($option, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the form element field have the specified value.
|
||||
* Checks that the field matches the specified value. When using multi-select fields use commas to separate selected options.
|
||||
*
|
||||
* @Then /^the "(?P<field_string>(?:[^"]|\\")*)" field should match "(?P<value_string>(?:[^"]|\\")*)" value$/
|
||||
* @throws ExpectationException
|
||||
@@ -248,10 +264,10 @@ class behat_forms extends behat_base {
|
||||
|
||||
// Get the field.
|
||||
$field = behat_field_manager::get_form_field($fieldnode, $this->getSession());
|
||||
$fieldvalue = $field->get_value();
|
||||
|
||||
// Checks if the provided value matches the current field value.
|
||||
if (trim($value) != trim($fieldvalue)) {
|
||||
if (!$field->matches($value)) {
|
||||
$fieldvalue = $field->get_value();
|
||||
throw new ExpectationException(
|
||||
'The \'' . $locator . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' ,
|
||||
$this->getSession()
|
||||
@@ -259,26 +275,120 @@ class behat_forms extends behat_base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, the field matches the value. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
|
||||
*
|
||||
* Backport of Moodle 2.7 method to help backporting
|
||||
* features to 2.6.
|
||||
*
|
||||
* @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function the_field_matches_value($field, $value) {
|
||||
|
||||
$fieldnode = $this->find_field($field);
|
||||
|
||||
// Get the field.
|
||||
$formfield = behat_field_manager::get_form_field($fieldnode, $this->getSession());
|
||||
|
||||
// Checks if the provided value matches the current field value.
|
||||
if (!$formfield->matches($value)) {
|
||||
$fieldvalue = $formfield->get_value();
|
||||
throw new ExpectationException(
|
||||
'The \'' . $field . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' ,
|
||||
$this->getSession()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the form element field does not match the specified value.
|
||||
*
|
||||
* @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" does not match value "(?P<value_string>(?:[^"]|\\")*)"$/
|
||||
* @throws ExpectationException
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function the_field_does_not_match_value($field, $value) {
|
||||
|
||||
$fieldnode = $this->find_field($field);
|
||||
|
||||
// Get the field.
|
||||
$formfield = behat_field_manager::get_form_field($fieldnode, $this->getSession());
|
||||
|
||||
// Checks if the provided value matches the current field value.
|
||||
if ($formfield->matches($value)) {
|
||||
$fieldvalue = $formfield->get_value();
|
||||
throw new ExpectationException(
|
||||
'The \'' . $field . '\' value matches \'' . $value . '\' and it should not match it' ,
|
||||
$this->getSession()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if fields values matches the provided values. Provide a table with field/value data.
|
||||
*
|
||||
* @Then /^the following fields match these values:$/
|
||||
* @throws ExpectationException
|
||||
* @param TableNode $data Pairs of | field | value |
|
||||
*/
|
||||
public function the_following_fields_match_these_values(TableNode $data) {
|
||||
|
||||
// Expand all fields in case we have.
|
||||
$this->expand_all_fields();
|
||||
|
||||
$datahash = $data->getRowsHash();
|
||||
|
||||
// The action depends on the field type.
|
||||
foreach ($datahash as $locator => $value) {
|
||||
$this->the_field_should_match_value($locator, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that fields values do not match the provided values. Provide a table with field/value data.
|
||||
*
|
||||
* @Then /^the following fields do not match these values:$/
|
||||
* @throws ExpectationException
|
||||
* @param TableNode $data Pairs of | field | value |
|
||||
*/
|
||||
public function the_following_fields_do_not_match_these_values(TableNode $data) {
|
||||
|
||||
// Expand all fields in case we have.
|
||||
$this->expand_all_fields();
|
||||
|
||||
$datahash = $data->getRowsHash();
|
||||
|
||||
// The action depends on the field type.
|
||||
foreach ($datahash as $locator => $value) {
|
||||
$this->the_field_does_not_match_value($locator, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, that checkbox with specified in|name|label|value is checked.
|
||||
*
|
||||
* @Then /^the "(?P<checkbox_string>(?:[^"]|\\")*)" checkbox should be checked$/
|
||||
* @see Behat\MinkExtension\Context\MinkContext
|
||||
* @param string $checkbox
|
||||
*/
|
||||
public function assert_checkbox_checked($checkbox) {
|
||||
$this->assertSession()->checkboxChecked($checkbox);
|
||||
$this->the_field_should_match_value($checkbox, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, that checkbox with specified in|name|label|value is unchecked.
|
||||
*
|
||||
* @Then /^the "(?P<checkbox_string>(?:[^"]|\\")*)" checkbox should not be checked$/
|
||||
* @see Behat\MinkExtension\Context\MinkContext
|
||||
* @param string $checkbox
|
||||
*/
|
||||
public function assert_checkbox_not_checked($checkbox) {
|
||||
$this->assertSession()->checkboxNotChecked($checkbox);
|
||||
$this->the_field_should_match_value($checkbox, '');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,20 +398,41 @@ class behat_forms extends behat_base {
|
||||
* @throws ExpectationException
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $select The select element name
|
||||
* @param string $option The option text/value
|
||||
* @param string $option The option text/value. Plain value or comma separated
|
||||
* values if multiple. Commas in multiple values escaped with backslash.
|
||||
*/
|
||||
public function the_select_box_should_contain($select, $option) {
|
||||
|
||||
$selectnode = $this->find_field($select);
|
||||
$multiple = $selectnode->hasAttribute('multiple');
|
||||
$optionsarr = array(); // Array of passed value/text options to test.
|
||||
|
||||
$regex = '/' . preg_quote($option, '/') . '/ui';
|
||||
if (!preg_match($regex, $selectnode->getText())) {
|
||||
throw new ExpectationException(
|
||||
'The select box "' . $select . '" does not contains the option "' . $option . '"',
|
||||
$this->getSession()
|
||||
);
|
||||
if ($multiple) {
|
||||
// Can pass multiple comma separated, with valuable commas escaped with backslash.
|
||||
foreach (preg_replace('/\\\,/', ',', preg_split('/(?<!\\\),/', $option)) as $opt) {
|
||||
$optionsarr[] = trim($opt);
|
||||
}
|
||||
} else {
|
||||
// Only one option has been passed.
|
||||
$optionsarr[] = trim($option);
|
||||
}
|
||||
|
||||
// Now get all the values and texts in the select.
|
||||
$options = $selectnode->findAll('xpath', '//option');
|
||||
$values = array();
|
||||
foreach ($options as $opt) {
|
||||
$values[trim($opt->getValue())] = trim($opt->getText());
|
||||
}
|
||||
|
||||
foreach ($optionsarr as $opt) {
|
||||
// Verify every option is a valid text or value.
|
||||
if (!in_array($opt, $values) && !array_key_exists($opt, $values)) {
|
||||
throw new ExpectationException(
|
||||
'The select box "' . $select . '" does not contain the option "' . $opt . '"',
|
||||
$this->getSession()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,19 +442,61 @@ class behat_forms extends behat_base {
|
||||
* @throws ExpectationException
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $select The select element name
|
||||
* @param string $option The option text/value
|
||||
* @param string $option The option text/value. Plain value or comma separated
|
||||
* values if multiple. Commas in multiple values escaped with backslash.
|
||||
*/
|
||||
public function the_select_box_should_not_contain($select, $option) {
|
||||
|
||||
$selectnode = $this->find_field($select);
|
||||
$multiple = $selectnode->hasAttribute('multiple');
|
||||
$optionsarr = array(); // Array of passed value/text options to test.
|
||||
|
||||
$regex = '/' . preg_quote($option, '/') . '/ui';
|
||||
if (preg_match($regex, $selectnode->getText())) {
|
||||
throw new ExpectationException(
|
||||
'The select box "' . $select . '" contains the option "' . $option . '"',
|
||||
$this->getSession()
|
||||
);
|
||||
if ($multiple) {
|
||||
// Can pass multiple comma separated, with valuable commas escaped with backslash.
|
||||
foreach (preg_replace('/\\\,/', ',', preg_split('/(?<!\\\),/', $option)) as $opt) {
|
||||
$optionsarr[] = trim($opt);
|
||||
}
|
||||
} else {
|
||||
// Only one option has been passed.
|
||||
$optionsarr[] = trim($option);
|
||||
}
|
||||
|
||||
// Now get all the values and texts in the select.
|
||||
$options = $selectnode->findAll('xpath', '//option');
|
||||
$values = array();
|
||||
foreach ($options as $opt) {
|
||||
$values[trim($opt->getValue())] = trim($opt->getText());
|
||||
}
|
||||
|
||||
foreach ($optionsarr as $opt) {
|
||||
// Verify every option is not a valid text or value.
|
||||
if (in_array($opt, $values) || array_key_exists($opt, $values)) {
|
||||
throw new ExpectationException(
|
||||
'The select box "' . $select . '" contains the option "' . $opt . '"',
|
||||
$this->getSession()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic field setter.
|
||||
*
|
||||
* Internal API method, a generic *I set "VALUE" to "FIELD" field*
|
||||
* could be created based on it.
|
||||
*
|
||||
* @param string $fieldlocator The pointer to the field, it will depend on the field type.
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
protected function set_field_value($fieldlocator, $value) {
|
||||
|
||||
$node = $this->find_field($fieldlocator);
|
||||
|
||||
// We delegate to behat_form_field class, it will
|
||||
// guess the type properly as it is a select tag.
|
||||
$field = behat_field_manager::get_form_field($node, $this->getSession());
|
||||
$field->set_value($value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -142,4 +142,44 @@ class behat_permissions extends behat_base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the capability has the specified permission. Works in the role definition advanced page.
|
||||
*
|
||||
* @Then /^"(?P<capability_string>(?:[^"]|\\")*)" capability has "(?P<permission_string>Not set|Allow|Prevent|Prohibit)" permission$/
|
||||
* @throws ExpectationException
|
||||
* @param string $capabilityname
|
||||
* @param string $permission
|
||||
* @return void
|
||||
*/
|
||||
public function capability_has_permission($capabilityname, $permission) {
|
||||
|
||||
// We already know the name, so we just need the value.
|
||||
$radioxpath = "//table[@class='rolecap']/descendant::input[@type='radio']" .
|
||||
"[@name='" . $capabilityname . "'][@checked]";
|
||||
|
||||
$checkedradio = $this->find('xpath', $radioxpath);
|
||||
|
||||
switch ($permission) {
|
||||
case get_string('notset', 'role'):
|
||||
$perm = CAP_INHERIT;
|
||||
break;
|
||||
case get_string('allow', 'role'):
|
||||
$perm = CAP_ALLOW;
|
||||
break;
|
||||
case get_string('prevent', 'role'):
|
||||
$perm = CAP_PREVENT;
|
||||
break;
|
||||
case get_string('prohibit', 'role'):
|
||||
$perm = CAP_PROHIBIT;
|
||||
break;
|
||||
default:
|
||||
throw new ExpectationException('"' . $permission . '" permission does not exist', $this->getSession());
|
||||
break;
|
||||
}
|
||||
|
||||
if ($checkedradio->getAttribute('value') != $perm) {
|
||||
throw new ExpectationException('"' . $capabilityname . '" permission is not "' . $permission . '"', $this->getSession());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user