mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
Merge branch 'MDL-42625_master' of git://github.com/dmonllao/moodle
This commit is contained in:
commit
ebc77165a4
51 changed files with 991 additions and 335 deletions
|
@ -29,14 +29,12 @@ Feature: Toggle activities groups mode from the course page
|
|||
Then "No groups (Click to change)" "link" should exists
|
||||
And "//a/child::img[contains(@src, 'groupn')]" "xpath_element" should exists
|
||||
And I click on "No groups (Click to change)" "link" in the "Test forum name" activity
|
||||
And I wait "3" seconds
|
||||
And "Separate groups (Click to change)" "link" should exists
|
||||
And "//a/child::img[contains(@src, 'groups')]" "xpath_element" should exists
|
||||
And I reload the page
|
||||
And "Separate groups (Click to change)" "link" should exists
|
||||
And "//a/child::img[contains(@src, 'groups')]" "xpath_element" should exists
|
||||
And I click on "Separate groups (Click to change)" "link" in the "Test forum name" activity
|
||||
And I wait "3" seconds
|
||||
And "Visible groups (Click to change)" "link" should exists
|
||||
And "//a/child::img[contains(@src, 'groupv')]" "xpath_element" should exists
|
||||
And I reload the page
|
||||
|
|
|
@ -40,8 +40,10 @@ Feature: Add activities to courses
|
|||
Scenario: Add an activity without the required fields
|
||||
When I add a "Database" to section "3" and I fill the form with:
|
||||
| Name | Test name |
|
||||
And I press "Save and return to course"
|
||||
Then I should see "Adding a new"
|
||||
And I should see "Required"
|
||||
And I press "Cancel"
|
||||
|
||||
Scenario: Add an activity to a course with Javascript disabled
|
||||
Then I should see "Add a resource to section 'Topic 1'"
|
||||
|
|
|
@ -67,15 +67,50 @@ class behat_course extends behat_base {
|
|||
* @return Given[]
|
||||
*/
|
||||
public function i_create_a_course_with(TableNode $table) {
|
||||
return array(
|
||||
|
||||
$steps = array(
|
||||
new Given('I go to the courses management page'),
|
||||
new Given('I should see the "'.get_string('categories').'" management page'),
|
||||
new Given('I click on category "'.get_string('miscellaneous').'" in the management interface'),
|
||||
new Given('I should see the "'.get_string('categoriesandcoures').'" management page'),
|
||||
new Given('I click on "'.get_string('createnewcourse').'" "link" in the "#course-listing" "css_element"'),
|
||||
new Given('I fill the moodle form with:', $table),
|
||||
new Given('I press "' . get_string('savechanges') . '"')
|
||||
new Given('I click on "'.get_string('createnewcourse').'" "link" in the "#course-listing" "css_element"')
|
||||
);
|
||||
|
||||
// If the course format is one of the fields we change how we
|
||||
// fill the form as we need to wait for the form to be set.
|
||||
$rowshash = $table->getRowsHash();
|
||||
$formatfieldrefs = array(get_string('format'), 'format', 'id_format');
|
||||
foreach ($formatfieldrefs as $fieldref) {
|
||||
if (!empty($rowshash[$fieldref])) {
|
||||
$formatfield = $fieldref;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the format separately.
|
||||
if (!empty($formatfield)) {
|
||||
|
||||
// Removing the format field from the TableNode.
|
||||
$rows = $table->getRows();
|
||||
$formatvalue = $rowshash[$formatfield];
|
||||
foreach ($rows as $key => $row) {
|
||||
if ($row[0] == $formatfield) {
|
||||
unset($rows[$key]);
|
||||
}
|
||||
}
|
||||
$table->setRows($rows);
|
||||
|
||||
// Adding a forced wait until editors are loaded as otherwise selenium sometimes tries clicks on the
|
||||
// format field when the editor is being rendered and the click misses the field coordinates.
|
||||
$steps[] = new Given('I wait until the editors are loaded');
|
||||
$steps[] = new Given('I select "' . $formatvalue . '" from "' . $formatfield . '"');
|
||||
$steps[] = new Given('I fill the moodle form with:', $table);
|
||||
} else {
|
||||
$steps[] = new Given('I fill the moodle form with:', $table);
|
||||
}
|
||||
|
||||
$steps[] = new Given('I press "' . get_string('savechanges') . '"');
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,10 +216,7 @@ class behat_course extends behat_base {
|
|||
// Ensures the section exists.
|
||||
$xpath = $this->section_exists($sectionnumber);
|
||||
|
||||
return array(
|
||||
new Given('I click on "' . get_string('markthistopic') . '" "link" in the "' . $this->escape($xpath) . '" "xpath_element"'),
|
||||
new Given('I wait "2" seconds')
|
||||
);
|
||||
return new Given('I click on "' . get_string('markthistopic') . '" "link" in the "' . $this->escape($xpath) . '" "xpath_element"');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,10 +231,7 @@ class behat_course extends behat_base {
|
|||
// Ensures the section exists.
|
||||
$xpath = $this->section_exists($sectionnumber);
|
||||
|
||||
return array(
|
||||
new Given('I click on "' . get_string('markedthistopic') . '" "link" in the "' . $this->escape($xpath) . '" "xpath_element"'),
|
||||
new Given('I wait "2" seconds')
|
||||
);
|
||||
return new Given('I click on "' . get_string('markedthistopic') . '" "link" in the "' . $this->escape($xpath) . '" "xpath_element"');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,9 +244,9 @@ class behat_course extends behat_base {
|
|||
$showlink = $this->show_section_icon_exists($sectionnumber);
|
||||
$showlink->click();
|
||||
|
||||
// It requires time.
|
||||
if ($this->running_javascript()) {
|
||||
$this->getSession()->wait(5000, false);
|
||||
$this->getSession()->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
|
||||
$this->i_wait_until_section_is_available($sectionnumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,9 +260,9 @@ class behat_course extends behat_base {
|
|||
$hidelink = $this->hide_section_icon_exists($sectionnumber);
|
||||
$hidelink->click();
|
||||
|
||||
// It requires time.
|
||||
if ($this->running_javascript()) {
|
||||
$this->getSession()->wait(5000, false);
|
||||
$this->getSession()->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
|
||||
$this->i_wait_until_section_is_available($sectionnumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,6 +343,11 @@ class behat_course extends behat_base {
|
|||
|
||||
$sectionxpath = $this->section_exists($sectionnumber);
|
||||
|
||||
// Preventive in case there is any action in progress.
|
||||
// Adding it here because we are interacting (click) with
|
||||
// the elements, not necessary when we just find().
|
||||
$this->i_wait_until_section_is_available($sectionnumber);
|
||||
|
||||
// Section should be hidden.
|
||||
$exception = new ExpectationException('The section is not hidden', $this->getSession());
|
||||
$this->find('xpath', $sectionxpath . "[contains(concat(' ', normalize-space(@class), ' '), ' hidden ')]", $exception);
|
||||
|
@ -338,9 +372,12 @@ class behat_course extends behat_base {
|
|||
// Non-JS browsers can not click on img elements.
|
||||
if ($this->running_javascript()) {
|
||||
|
||||
// Expanding the actions menu.
|
||||
$actionsmenu = $this->find('css', "a[role='menuitem']", false, $activity);
|
||||
$actionsmenu->click();
|
||||
// Expanding the actions menu if it is not shown.
|
||||
$classes = array_flip(explode(' ', $activity->getAttribute('class')));
|
||||
if (empty($classes['action-menu-shown'])) {
|
||||
$actionsmenu = $this->find('css', "a[role='menuitem']", false, $activity);
|
||||
$actionsmenu->click();
|
||||
}
|
||||
|
||||
// To check that the visibility is not clickable we check the funcionality rather than the applied style.
|
||||
$visibilityiconnode = $this->find('css', 'a.editing_show img', false, $activity);
|
||||
|
@ -349,6 +386,17 @@ class behat_course extends behat_base {
|
|||
|
||||
// We ensure that we still see the show icon.
|
||||
$visibilityiconnode = $this->find('css', 'a.editing_show img', $visibilityexception, $activity);
|
||||
|
||||
// It is there only when running JS scenarios.
|
||||
if ($this->running_javascript()) {
|
||||
|
||||
// Collapse the actions menu if it is displayed.
|
||||
$classes = array_flip(explode(' ', $activity->getAttribute('class')));
|
||||
if (!empty($classes['action-menu-shown'])) {
|
||||
$actionsmenu = $this->find('css', "a[role='menuitem']", false, $activity);
|
||||
$actionsmenu->click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -543,8 +591,7 @@ class behat_course extends behat_base {
|
|||
$activity = $this->escape($activityname);
|
||||
return array(
|
||||
new Given('I click on "' . get_string('edittitle') . '" "link" in the "' . $activity .'" activity'),
|
||||
new Given('I fill in "title" with "' . $this->escape($newactivityname) . chr(10) . '"'),
|
||||
new Given('I wait "2" seconds')
|
||||
new Given('I fill in "title" with "' . $this->escape($newactivityname) . chr(10) . '"')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -572,6 +619,30 @@ class behat_course extends behat_base {
|
|||
return new Given('I click on "a[role=\'menuitem\']" "css_element" in the "' . $this->escape($activityname) . '" activity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an activity actions menu if it is not already closed.
|
||||
*
|
||||
* @Given /^I close "(?P<activity_name_string>(?:[^"]|\\")*)" actions menu$/
|
||||
* @throws DriverException The step is not available when Javascript is disabled
|
||||
* @param string $activityname
|
||||
* @return Given
|
||||
*/
|
||||
public function i_close_actions_menu($activityname) {
|
||||
|
||||
if (!$this->running_javascript()) {
|
||||
throw new DriverException('Activities actions menu not available when Javascript is disabled');
|
||||
}
|
||||
|
||||
// If it is already closed we do nothing.
|
||||
$activitynode = $this->get_activity_node($activityname);
|
||||
$classes = array_flip(explode(' ', $activitynode->getAttribute('class')));
|
||||
if (empty($classes['action-menu-shown'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Given('I click on "a[role=\'menuitem\']" "css_element" in the "' . $this->escape($activityname) . '" activity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents to the right the activity or resource specified by it's name. Editing mode should be on.
|
||||
*
|
||||
|
@ -588,10 +659,6 @@ class behat_course extends behat_base {
|
|||
}
|
||||
$steps[] = new Given('I click on "' . get_string('moveright') . '" "link" in the "' . $activity . '" activity');
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I wait "2" seconds');
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
|
@ -611,10 +678,6 @@ class behat_course extends behat_base {
|
|||
}
|
||||
$steps[] = new Given('I click on "' . get_string('moveleft') . '" "link" in the "' . $activity . '" activity');
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I wait "2" seconds');
|
||||
}
|
||||
|
||||
return $steps;
|
||||
|
||||
}
|
||||
|
@ -640,8 +703,6 @@ class behat_course extends behat_base {
|
|||
|
||||
$this->getSession()->getDriver()->getWebDriverSession()->accept_alert();
|
||||
|
||||
$this->getSession()->wait(2 * 1000, false);
|
||||
|
||||
} else {
|
||||
|
||||
// With JS disabled.
|
||||
|
@ -668,10 +729,7 @@ class behat_course extends behat_base {
|
|||
$steps[] = new Given('I open "' . $activity . '" actions menu');
|
||||
}
|
||||
$steps[] = new Given('I click on "' . get_string('duplicate') . '" "link" in the "' . $activity . '" activity');
|
||||
if ($this->running_javascript()) {
|
||||
// Temporary wait until MDL-41030 lands.
|
||||
$steps[] = new Given('I wait "4" seconds');
|
||||
} else {
|
||||
if (!$this->running_javascript()) {
|
||||
$steps[] = new Given('I press "' . get_string('continue') .'"');
|
||||
$steps[] = new Given('I press "' . get_string('duplicatecontcourse') .'"');
|
||||
}
|
||||
|
@ -691,12 +749,22 @@ class behat_course extends behat_base {
|
|||
$steps = array();
|
||||
|
||||
$activity = $this->escape($activityname);
|
||||
$activityliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($activityname);
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I duplicate "' . $activity . '" activity');
|
||||
|
||||
// We wait until the AJAX request finishes and the section is visible again.
|
||||
$hiddenlightboxxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][contains(., $activityliteral)]" .
|
||||
"/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" .
|
||||
"/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]";
|
||||
$steps[] = new Given('I wait until the page is ready');
|
||||
$steps[] = new Given('I wait until "' . $this->escape($hiddenlightboxxpath) .'" "xpath_element" exists');
|
||||
|
||||
// Close the original activity actions menu.
|
||||
$steps[] = new Given('I close "' . $activity . '" actions menu');
|
||||
|
||||
// Determine the future new activity xpath from the former one.
|
||||
$activityliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($activityname);
|
||||
$duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][contains(., $activityliteral)]" .
|
||||
"/following-sibling::li";
|
||||
$duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']";
|
||||
|
@ -717,6 +785,32 @@ class behat_course extends behat_base {
|
|||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the section is available to interact with it. Useful when the section is performing an action and the section is overlayed with a loading layout.
|
||||
*
|
||||
* Using the protected method as this method will be usually
|
||||
* called by other methods which are not returning a set of
|
||||
* steps and performs the actions directly, so it would not
|
||||
* be executed if it returns another step.
|
||||
*
|
||||
* Hopefully we would not require test writers to use this step
|
||||
* and we will manage it from other step definitions.
|
||||
*
|
||||
* @Given /^I wait until section "(?P<section_number>\d+)" is available$/
|
||||
* @param int $sectionnumber
|
||||
* @return void
|
||||
*/
|
||||
public function i_wait_until_section_is_available($sectionnumber) {
|
||||
|
||||
// Looks for a hidden lightbox or a non-existent lightbox in that section.
|
||||
$sectionxpath = $this->section_exists($sectionnumber);
|
||||
$hiddenlightboxxpath = $sectionxpath . "/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]" .
|
||||
" | " .
|
||||
$sectionxpath . "[count(child::div[contains(@class, 'lightbox')]) = 0]";
|
||||
|
||||
$this->ensure_element_exists($hiddenlightboxxpath, 'xpath_element');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks on the specified element of the activity. You should be in the course page with editing mode turned on.
|
||||
*
|
||||
|
@ -882,6 +976,18 @@ class behat_course extends behat_base {
|
|||
return $this->find('xpath', $xpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the activity instance name from the activity node.
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
* @param NodeElement $activitynode
|
||||
* @return string
|
||||
*/
|
||||
protected function get_activity_name($activitynode) {
|
||||
$instancenamenode = $this->find('xpath', "//span[contains(concat(' ', normalize-space(@class), ' '), ' instancename ')]", false, $activitynode);
|
||||
return $instancenamenode->getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user can edit the course contents or not.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@core @core_course @test
|
||||
@core @core_course
|
||||
Feature: Course category management interface performs as expected
|
||||
In order to test JS enhanced display of categories and subcategories.
|
||||
As a moodle admin
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@core @core_course
|
||||
@core @core_course @_alerts
|
||||
Feature: Course activity controls works as expected
|
||||
In order to manage my course's activities
|
||||
As a teacher
|
||||
|
@ -59,11 +59,16 @@ Feature: Course activity controls works as expected
|
|||
And I click on "Edit settings" "link" in the "Test forum name 1" activity
|
||||
And I should see "Updating Forum"
|
||||
And I should see "Display description on course page"
|
||||
And I press "Save and return to course"
|
||||
And I fill the moodle form with:
|
||||
| Forum name | Just to check that I can edit the name |
|
||||
| Description | Just to check that I can edit the description |
|
||||
| Display description on course page | 1 |
|
||||
And I click on "Cancel" "button"
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I open "Test forum name 1" actions menu
|
||||
And I click on "Hide" "link" in the "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I close "Test forum name 1" actions menu
|
||||
And I duplicate "Test forum name 2" activity editing the new copy with:
|
||||
| Forum name | Edited test forum name 2 |
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue