MDL-58428 theme: Shift templates ready for Bootstrapbase removal

Move behat override steps from boost into their Moodle core locations &
Move the effected core behat steps into bootstrapbase as override steps.
This commit is contained in:
Mathew May 2019-01-16 12:03:40 +08:00
parent 07203d34f1
commit e3652936f3
25 changed files with 892 additions and 932 deletions

View File

@ -55,16 +55,12 @@ class behat_admin extends behat_base {
foreach ($data as $label => $value) {
// We expect admin block to be visible, otherwise go to homepage.
if (!$this->getSession()->getPage()->find('css', '.block_settings')) {
$this->getSession()->visit($this->locate_path('/'));
$this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
}
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', [get_string('administrationsite')]);
// Search by label.
$searchbox = $this->find_field(get_string('searchinsettings', 'admin'));
$searchbox = $this->find_field(get_string('query', 'admin'));
$searchbox->setValue($label);
$submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]');
$submitsearch = $this->find('css', 'form input[type=submit][name=search]');
$submitsearch->press();
$this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
@ -78,21 +74,24 @@ class behat_admin extends behat_base {
// Single element settings.
try {
$fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" .
"[@id=//label[contains(normalize-space(.), $label)]/@for or " .
"@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]";
$fieldxpath = "//*[self::input | self::textarea | self::select]" .
"[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" .
"[@id=//label[contains(normalize-space(.), $label)]/@for or " .
"@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]";
$fieldnode = $this->find('xpath', $fieldxpath, $exception);
$formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']" .
"/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div");
$formfieldtypenode = $this->find('xpath', $fieldxpath .
"/ancestor::div[contains(concat(' ', @class, ' '), ' form-setting ')]" .
"/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div");
} catch (ElementNotFoundException $e) {
// Multi element settings, interacting only the first one.
$fieldxpath = "//*[label[normalize-space(.)= $label]|span[normalize-space(.)= $label]]/" .
"ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
"/descendant::div[@class='form-group']/descendant::*[self::input | self::textarea | self::select]" .
"[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]";
$fieldxpath = "//*[label[contains(., $label)]|span[contains(., $label)]]" .
"/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
"/descendant::div[contains(concat(' ', @class, ' '), ' form-group ')]" .
"/descendant::*[self::input | self::textarea | self::select]" .
"[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]";
$fieldnode = $this->find('xpath', $fieldxpath);
// It is the same one that contains the type.
@ -101,6 +100,7 @@ class behat_admin extends behat_base {
// Getting the class which contains the field type.
$classes = explode(' ', $formfieldtypenode->getAttribute('class'));
$type = false;
foreach ($classes as $class) {
if (substr($class, 0, 5) == 'form-') {
$type = substr($class, 5);

View File

@ -46,15 +46,13 @@ class behat_blocks extends behat_base {
* @param string $blockname
*/
public function i_add_the_block($blockname) {
$this->execute('behat_forms::i_set_the_field_to',
array("bui_addblock", $this->escape($blockname))
);
$addblock = get_string('addblock');
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock);
// If we are running without javascript we need to submit the form.
if (!$this->running_javascript()) {
$this->execute('behat_general::i_click_on_in_the',
array(get_string('go'), "button", "#add_block", "css_element")
);
$this->execute('behat_general::i_click_on_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']);
} else {
$this->execute('behat_general::i_click_on_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']);
}
}
@ -108,7 +106,7 @@ class behat_blocks extends behat_base {
}
$this->execute('behat_general::i_click_on_in_the',
array(get_string('actions'), "link", $this->escape($blockname), "block")
array("a[data-toggle='dropdown']", "css_element", $this->escape($blockname), "block")
);
}
@ -137,7 +135,17 @@ class behat_blocks extends behat_base {
* @param string $blockname
*/
public function the_add_block_selector_should_contain_block($blockname) {
$this->execute('behat_forms::the_select_box_should_contain', [get_string('addblock'), $blockname]);
$addblock = get_string('addblock');
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock);
$cancelstr = get_string('cancel');
if (!$this->running_javascript()) {
$this->execute('behat_general::should_exist_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'link_exact', '#region-main', 'css_element']);
} else {
$this->execute('behat_general::should_exist_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'button', $addblock, 'dialogue']);
}
}
/**
@ -147,6 +155,16 @@ class behat_blocks extends behat_base {
* @param string $blockname
*/
public function the_add_block_selector_should_not_contain_block($blockname) {
$this->execute('behat_forms::the_select_box_should_not_contain', [get_string('addblock'), $blockname]);
$addblock = get_string('addblock');
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock);
$cancelstr = get_string('cancel');
if (!$this->running_javascript()) {
$this->execute('behat_general::should_not_exist_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'link_exact', '#region-main', 'css_element']);
} else {
$this->execute('behat_general::should_not_exist_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'button', $addblock, 'dialogue']);
}
}
}

View File

@ -186,10 +186,11 @@ class behat_course extends behat_base {
// We are on the frontpage.
if ($section) {
// Section 1 represents the contents on the frontpage.
$sectionxpath = "//body[@id='page-site-index']/descendant::div[contains(concat(' ',normalize-space(@class),' '),' sitetopic ')]";
$sectionxpath = "//body[@id='page-site-index']" .
"/descendant::div[contains(concat(' ',normalize-space(@class),' '),' sitetopic ')]";
} else {
// Section 0 represents "Site main menu" block.
$sectionxpath = "//div[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]";
$sectionxpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]";
}
} else {
// We are inside the course.
@ -201,15 +202,16 @@ class behat_course extends behat_base {
if ($this->running_javascript()) {
// Clicks add activity or resource section link.
$sectionxpath = $sectionxpath . "/descendant::div[@class='section-modchooser']/span/a";
$sectionxpath = $sectionxpath . "/descendant::div" .
"[contains(concat(' ', normalize-space(@class) , ' '), ' section-modchooser ')]/span/a";
$sectionnode = $this->find('xpath', $sectionxpath);
$sectionnode->click();
// Clicks the selected activity if it exists.
$activityxpath = "//div[@id='chooseform']/descendant::label" .
"/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" .
"[normalize-space(.)=$activityliteral]" .
"/parent::label/child::input";
"/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" .
"[normalize-space(.)=$activityliteral]" .
"/parent::label/child::input";
$activitynode = $this->find('xpath', $activityxpath);
$activitynode->doubleClick();
@ -217,8 +219,9 @@ class behat_course extends behat_base {
// Without Javascript.
// Selecting the option from the select box which contains the option.
$selectxpath = $sectionxpath . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' section_add_menus ')]" .
"/descendant::select[option[normalize-space(.)=$activityliteral]]";
$selectxpath = $sectionxpath . "/descendant::div" .
"[contains(concat(' ', normalize-space(@class), ' '), ' section_add_menus ')]" .
"/descendant::select[option[normalize-space(.)=$activityliteral]]";
$selectnode = $this->find('xpath', $selectxpath);
$selectnode->selectOption($activity);
@ -230,7 +233,6 @@ class behat_course extends behat_base {
}
/**
* Opens a section edit menu if it is not already opened.
*
@ -248,7 +250,7 @@ class behat_course extends behat_base {
// If it is already opened we do nothing.
$xpath = $this->section_exists($sectionnumber);
$xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@class, 'textmenu')]";
$xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@data-toggle, 'dropdown')]";
$exception = new ExpectationException('Section "' . $sectionnumber . '" was not found', $this->getSession());
$menu = $this->find('xpath', $xpath, $exception);
@ -550,8 +552,8 @@ class behat_course extends behat_base {
// Edit menu should be visible.
if ($this->is_course_editor()) {
$xpath = $sectionxpath .
"/descendant::div[contains(@class, 'section-actions')]" .
"/descendant::a[contains(@class, 'textmenu')]";
"/descendant::div[contains(@class, 'section-actions')]" .
"/descendant::a[contains(@data-toggle, 'dropdown')]";
if (!$this->getSession()->getPage()->find('xpath', $xpath)) {
throw new ExpectationException('The section edit menu is not available', $this->getSession());
}
@ -843,15 +845,23 @@ class behat_course extends behat_base {
// If it is already opened we do nothing.
$activitynode = $this->get_activity_node($activityname);
$classes = array_flip(explode(' ', $activitynode->getAttribute('class')));
if (!empty($classes['action-menu-shown'])) {
// Find the menu.
$menunode = $activitynode->find('css', 'a[data-toggle=dropdown]');
if (!$menunode) {
throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname),
$this->getSession());
}
$expanded = $menunode->getAttribute('aria-expanded');
if ($expanded == 'true') {
return;
}
$this->execute('behat_course::i_click_on_in_the_activity',
array("a[role='menuitem']", "css_element", $this->escape($activityname))
array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname))
);
$this->actions_menu_should_be_open($activityname);
}
/**
@ -869,13 +879,19 @@ class behat_course extends behat_base {
// 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'])) {
// Find the menu.
$menunode = $activitynode->find('css', 'a[data-toggle=dropdown]');
if (!$menunode) {
throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname),
$this->getSession());
}
$expanded = $menunode->getAttribute('aria-expanded');
if ($expanded != 'true') {
return;
}
$this->execute('behat_course::i_click_on_in_the_activity',
array("a[role='menuitem']", "css_element", $this->escape($activityname))
array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname))
);
}
@ -892,10 +908,15 @@ class behat_course extends behat_base {
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'])) {
// Find the menu.
$menunode = $activitynode->find('css', 'a[data-toggle=dropdown]');
if (!$menunode) {
throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname),
$this->getSession());
}
$expanded = $menunode->getAttribute('aria-expanded');
if ($expanded != 'true') {
throw new ExpectationException(sprintf("The action menu for '%s' is not open", $activityname), $this->getSession());
}
}
@ -1039,18 +1060,18 @@ class behat_course extends behat_base {
// Determine the future new activity xpath from the former one.
$duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" .
"[contains(., $activityliteral)]/following-sibling::li";
$duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']";
"[contains(., $activityliteral)]/following-sibling::li";
$duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@data-toggle='dropdown']";
if ($this->running_javascript()) {
// 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')]";
"[contains(., $activityliteral)]" .
"/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" .
"/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]";
$this->execute("behat_general::wait_until_exists",
array($this->escape($hiddenlightboxxpath), "xpath_element")
array($this->escape($hiddenlightboxxpath), "xpath_element")
);
// Close the original activity actions menu.
@ -1059,13 +1080,13 @@ class behat_course extends behat_base {
// The next sibling of the former activity will be the duplicated one, so we click on it from it's xpath as, at
// this point, it don't even exists in the DOM (the steps are executed when we return them).
$this->execute('behat_general::i_click_on',
array($this->escape($duplicatedactionsmenuxpath), "xpath_element")
array($this->escape($duplicatedactionsmenuxpath), "xpath_element")
);
}
// We force the xpath as otherwise mink tries to interact with the former one.
$this->execute('behat_general::i_click_on_in_the',
array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element")
array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element")
);
$this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data);
@ -1281,8 +1302,8 @@ class behat_course extends behat_base {
protected function is_course_editor() {
// We don't need to behat_base::spin() here as all is already loaded.
if (!$this->getSession()->getPage()->findButton(get_string('turneditingoff')) &&
!$this->getSession()->getPage()->findButton(get_string('turneditingon'))) {
if (!$this->getSession()->getPage()->findLink(get_string('turneditingoff')) &&
!$this->getSession()->getPage()->findLink(get_string('turneditingon'))) {
return false;
}
@ -1842,7 +1863,8 @@ class behat_course extends behat_base {
* @throws Behat\Mink\Exception\ExpectationException
*/
protected function user_clicks_on_management_listing_action($listingtype, $listingnode, $action) {
$actionsnode = $listingnode->find('xpath', "//*[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]");
$actionsnode = $listingnode->find('xpath', "//*" .
"[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]");
if (!$actionsnode) {
throw new ExpectationException("Could not find the actions for $listingtype", $this->getSession());
}
@ -1851,7 +1873,7 @@ class behat_course extends behat_base {
throw new ExpectationException("Expected action was not available or not found ($action)", $this->getSession());
}
if ($this->running_javascript() && !$actionnode->isVisible()) {
$actionsnode->find('css', 'a.toggle-display')->click();
$actionsnode->find('css', 'a[data-toggle=dropdown]')->click();
$actionnode = $actionsnode->find('css', '.action-'.$action);
}
$actionnode->click();
@ -1874,10 +1896,7 @@ class behat_course extends behat_base {
* @Given /^I navigate to course participants$/
*/
public function i_navigate_to_course_participants() {
$coursestr = behat_context_helper::escape(get_string('courses'));
$mycoursestr = behat_context_helper::escape(get_string('mycourses'));
$xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]";
$this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']);
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('participants'));
}
/**

View File

@ -76,15 +76,18 @@ class behat_grade extends behat_base {
$gradeitem = behat_context_helper::escape($gradeitem);
if ($this->running_javascript()) {
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]";
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
$this->execute("behat_action_menu::i_open_the_action_menu_in",
array("//tr[contains(.,$gradeitem)]",
"xpath_element"));
}
}
$savechanges = get_string('savechanges', 'grades');
$edit = behat_context_helper::escape(get_string('edit') . ' ');
$linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " .
"and starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
$this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data);
@ -128,16 +131,19 @@ class behat_grade extends behat_base {
$gradeitem = behat_context_helper::escape($gradeitem);
if ($this->running_javascript()) {
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]";
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
$this->execute("behat_action_menu::i_open_the_action_menu_in",
array("//tr[contains(.,$gradeitem)]",
"xpath_element"));
}
}
// Going to edit calculation.
$savechanges = get_string('savechanges', 'grades');
$edit = behat_context_helper::escape(get_string('editcalculation', 'grades'));
$linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " .
"and starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
// Mapping names to idnumbers.
@ -145,11 +151,12 @@ class behat_grade extends behat_base {
foreach ($datahash as $gradeitem => $idnumber) {
// This xpath looks for course, categories and items with the provided name.
// Grrr, we can't equal in categoryitem and courseitem because there is a line jump...
$inputxpath ="//input[@class='idnumber'][" .
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" or " .
"parent::li[@class='categoryitem' or @class='courseitem']/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
$inputxpath = "//input[@class='idnumber'][" .
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" or " .
"parent::li[@class='categoryitem' or @class='courseitem']" .
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
$this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber));
}
@ -174,17 +181,18 @@ class behat_grade extends behat_base {
$gradeitem = behat_context_helper::escape($gradeitem);
if ($this->running_javascript()) {
$xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]" .
"//a[contains(@class,'toggle-display')]";
$xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
$xpath = "//tr[contains(.,$gradecategorytotal)]";
$this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element"));
}
}
// Going to edit calculation.
$savechanges = get_string('savechanges', 'grades');
$edit = behat_context_helper::escape(get_string('editcalculation', 'grades'));
$linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " .
"and starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
// Mapping names to idnumbers.
@ -193,11 +201,11 @@ class behat_grade extends behat_base {
// This xpath looks for course, categories and items with the provided name.
// Grrr, we can't equal in categoryitem and courseitem because there is a line jump...
$inputxpath = "//input[@class='idnumber'][" .
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" | " .
"parent::li[@class='categoryitem' | @class='courseitem']" .
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" | " .
"parent::li[@class='categoryitem' | @class='courseitem']" .
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
$this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber));
}
@ -221,9 +229,10 @@ class behat_grade extends behat_base {
if ($this->running_javascript()) {
$gradeitemliteral = behat_context_helper::escape($gradeitem);
$xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]";
$xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
$xpath = "//tr[contains(.,$gradeitemliteral)]";
$this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element"));
}
}
@ -290,11 +299,10 @@ class behat_grade extends behat_base {
* @param string $gradepath
*/
public function i_navigate_to_in_the_course_gradebook($gradepath) {
// If we are not on one of the gradebook pages already, follow "Grades" link in the navigation block.
// If we are not on one of the gradebook pages already, follow "Grades" link in the navigation drawer.
$xpath = '//div[contains(@class,\'grade-navigation\')]';
if (!$this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_general::i_click_on_in_the", array(get_string('grades'), 'link',
get_string('pluginname', 'block_navigation'), 'block'));
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('grades'));
}
$this->select_in_gradebook_tabs($gradepath);

View File

@ -58,6 +58,7 @@ class behat_files extends behat_base {
* @param string $filepickerelement The filepicker form field label
* @return NodeElement The hidden element node.
*/
protected function get_filepicker_node($filepickerelement) {
// More info about the problem (in case there is a problem).
@ -66,18 +67,18 @@ class behat_files extends behat_base {
// If no file picker label is mentioned take the first file picker from the page.
if (empty($filepickerelement)) {
$filepickercontainer = $this->find(
'xpath',
"//*[@data-fieldtype=\"filemanager\"]",
$exception
'xpath',
"//*[@data-fieldtype=\"filemanager\"]",
$exception
);
} else {
// Gets the ffilemanager node specified by the locator which contains the filepicker container.
$filepickerelement = behat_context_helper::escape($filepickerelement);
$filepickercontainer = $this->find(
'xpath',
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
'//ancestor::div[@data-fieldtype="filemanager" or @data-fieldtype="filepicker"]',
$exception
'xpath',
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
"//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
$exception
);
}

View File

@ -49,16 +49,11 @@ class behat_action_menu extends behat_base {
* @return void
*/
public function i_open_the_action_menu_in($element, $selectortype) {
if (!$this->running_javascript()) {
// Action menus automatically expand in a visible list of actions when Javascript is disabled.
return;
}
// Gets the node based on the requested selector type and locator.
$node = $this->get_node_in_container("css_element", "[role=menuitem][aria-haspopup=true]", $selectortype, $element);
$node = $this->get_node_in_container("css_element", "[role=button][aria-haspopup=true]", $selectortype, $element);
// Check if it is not already opened.
$menunode = $this->find('css', '[aria-labelledby='.$node->getAttribute('id').']');
if ($menunode->getAttribute('aria-hidden') === 'false') {
if ($node->getAttribute('aria-expanded') === 'true') {
return;
}
@ -73,15 +68,13 @@ class behat_action_menu extends behat_base {
* @param string $linkstring
* @return void
*/
public function i_choose_in_the_open_action_menu($linkstring) {
public function i_choose_in_the_open_action_menu($menuitemstring) {
if (!$this->running_javascript()) {
throw new DriverException('Action menu steps are not available with Javascript disabled');
}
// Gets the node based on the requested selector type and locator.
$node = $this->get_node_in_container("link",
$linkstring,
"css_element",
".moodle-actionmenu [role=menu][aria-hidden=false]");
$menuselector = ".moodle-actionmenu .dropdown.show .dropdown-menu";
$node = $this->get_node_in_container("link", $menuitemstring, "css_element", $menuselector);
$this->ensure_node_is_visible($node);
$node->click();
}

View File

@ -57,8 +57,6 @@ class behat_deprecated extends behat_base {
/**
* Click link in navigation tree that matches the text in parentnode/s (seperated using greater-than character if more than one)
*
* @Given /^I navigate to "(?P<nodetext_string>(?:[^"]|\\")*)" node in "(?P<parentnodes_string>(?:[^"]|\\")*)"$/
*
* @throws ExpectationException
* @param string $nodetext navigation node to click.
* @param string $parentnodes comma seperated list of parent nodes.
@ -78,7 +76,35 @@ class behat_deprecated extends behat_base {
$this->deprecated_message($alternative);
$parentnodes = array_map('trim', explode('>', $parentnodes));
$this->execute('behat_navigation::select_node_in_navigation', array($nodetext, $parentnodes));
$nodelist = array_merge($parentnodes, [$nodetext]);
$firstnode = array_shift($nodelist);
if ($firstnode === get_string('administrationsite')) {
$this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer',
array(get_string('administrationsite')));
$this->execute('behat_theme_boost_behat_navigation::select_on_administration_page', array($nodelist));
return;
}
if ($firstnode === get_string('sitepages')) {
if ($nodetext === get_string('calendar', 'calendar')) {
$this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer',
array(($nodetext)));
} else {
// TODO MDL-57120 other links under "Site pages" are not accessible without navigation block.
$this->execute('behat_theme_boost_behat_navigation::select_node_in_navigation',
array($nodetext, $parentnodes));
}
return;
}
if ($firstnode === get_string('courseadministration')) {
// Administration menu is available only on the main course page where settings in Administration
// block (original purpose of the step) are available on every course page.
$this->execute('behat_theme_boost_behat_navigation::go_to_main_course_page', array());
}
$this->execute('behat_theme_boost_behat_navigation::select_from_administration_menu', array($nodelist));
}
/**

View File

@ -29,6 +29,7 @@ require_once(__DIR__ . '/../../behat/behat_base.php');
use Behat\Mink\Exception\ExpectationException as ExpectationException;
use Behat\Mink\Exception\DriverException as DriverException;
use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
/**
* Steps definitions to navigate through the navigation tree nodes.
@ -150,16 +151,16 @@ class behat_navigation extends behat_base {
if ($this->running_javascript()) {
// The user menu must be expanded when JS is enabled.
$xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
$xpath = "//div[contains(concat(' ', @class, ' '), ' usermenu ')]//a[contains(concat(' ', @class, ' '), ' dropdown-toggle ')]";
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
// Now select the link.
// The CSS path is always present, with or without JS.
$csspath = ".usermenu [data-rel='menu-content']";
$csspath = ".usermenu .dropdown-menu";
$this->execute('behat_general::i_click_on_in_the',
array($nodetext, "link", $csspath, "css_element")
array($nodetext, "link", $csspath, "css_element")
);
}
@ -318,29 +319,17 @@ class behat_navigation extends behat_base {
$exception = new ExpectationException('Top navigation node "' . $nodetext . ' not found in "', $this->getSession());
// First find in navigation block.
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"[span[normalize-space(.)=" . $nodetextliteral ."] or a[normalize-space(.)=" . $nodetextliteral ."]]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/span[normalize-space(.)=" . $nodetextliteral ."]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/span[normalize-space(.)=" . $nodetextliteral ."]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/a[normalize-space(.)=" . $nodetextliteral ."]]";
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' card-text ')]" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/*[contains(normalize-space(.), " . $nodetextliteral .")]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' card-text ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/*[contains(normalize-space(.), " . $nodetextliteral .")]]";
$node = $this->find('xpath', $xpath, $exception);
@ -421,13 +410,8 @@ class behat_navigation extends behat_base {
* @return void
*/
public function i_navigate_to_in_current_page_administration($nodetext) {
$parentnodes = array_map('trim', explode('>', $nodetext));
// Find the name of the first category of the administration block tree.
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
$node = $this->find('xpath', $xpath);
array_unshift($parentnodes, $node->getText());
$lastnode = array_pop($parentnodes);
$this->select_node_in_navigation($lastnode, $parentnodes);
$nodelist = array_map('trim', explode('>', $nodetext));
$this->select_from_administration_menu($nodelist);
}
/**
@ -442,17 +426,15 @@ class behat_navigation extends behat_base {
* @return void
*/
public function should_exist_in_current_page_administration($element, $selectortype) {
$parentnodes = array_map('trim', explode('>', $element));
// Find the name of the first category of the administration block tree.
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
$node = $this->find('xpath', $xpath);
array_unshift($parentnodes, $node->getText());
$lastnode = array_pop($parentnodes);
$nodes = array_map('trim', explode('>', $element));
$nodetext = end($nodes);
if (!$this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) {
throw new ExpectationException(ucfirst($selectortype) . ' "' . $element .
'" not found in current page administration"', $this->getSession());
}
// Find administration menu.
$menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu(true);
$this->toggle_page_administration_menu($menuxpath);
$this->execute('behat_general::should_exist_in_the', [$nodetext, $selectortype, $menuxpath, 'xpath_element']);
$this->toggle_page_administration_menu($menuxpath);
}
/**
@ -467,17 +449,19 @@ class behat_navigation extends behat_base {
* @return void
*/
public function should_not_exist_in_current_page_administration($element, $selectortype) {
$parentnodes = array_map('trim', explode('>', $element));
// Find the name of the first category of the administration block tree.
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
$node = $this->find('xpath', $xpath);
array_unshift($parentnodes, $node->getText());
$lastnode = array_pop($parentnodes);
$nodes = array_map('trim', explode('>', $element));
$nodetext = end($nodes);
if ($this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) {
throw new ExpectationException(ucfirst($selectortype) . ' "' . $element .
'" found in current page administration"', $this->getSession());
// Find administration menu.
$menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu();
if (!$menuxpath) {
// Menu not found, exit.
return;
}
$this->toggle_page_administration_menu($menuxpath);
$this->execute('behat_general::should_not_exist_in_the', [$nodetext, $selectortype, $menuxpath, 'xpath_element']);
$this->toggle_page_administration_menu($menuxpath);
}
/**
@ -490,10 +474,9 @@ class behat_navigation extends behat_base {
* @return void
*/
public function i_navigate_to_in_site_administration($nodetext) {
$parentnodes = array_map('trim', explode('>', $nodetext));
array_unshift($parentnodes, get_string('administrationsite'));
$lastnode = array_pop($parentnodes);
$this->select_node_in_navigation($lastnode, $parentnodes);
$nodelist = array_map('trim', explode('>', $nodetext));
$this->i_select_from_flat_navigation_drawer(get_string('administrationsite'));
$this->select_on_administration_page($nodelist);
}
/**
@ -584,4 +567,209 @@ class behat_navigation extends behat_base {
$this->execute("behat_navigation::i_navigate_to_in_current_page_administration", [get_string('turneditingon')]);
}
}
/**
* Opens the flat navigation drawer if it is not already open
*
* @When /^I open flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
*/
public function i_open_flat_navigation_drawer() {
if (!$this->running_javascript()) {
// Navigation drawer is always open without JS.
return;
}
$xpath = "//button[contains(@data-action,'toggle-drawer')]";
$node = $this->find('xpath', $xpath);
$expanded = $node->getAttribute('aria-expanded');
if ($expanded === 'false') {
$node->click();
$this->ensure_node_attribute_is_set($node, 'aria-expanded', 'true');
$this->wait_for_pending_js();
}
}
/**
* Closes the flat navigation drawer if it is open (does nothing if JS disabled)
*
* @When /^I close flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
*/
public function i_close_flat_navigation_drawer() {
if (!$this->running_javascript()) {
// Navigation drawer can not be closed without JS.
return;
}
$xpath = "//button[contains(@data-action,'toggle-drawer')]";
$node = $this->find('xpath', $xpath);
$expanded = $node->getAttribute('aria-expanded');
if ($expanded === 'true') {
$node->click();
$this->wait_for_pending_js();
}
}
/**
* Clicks link with specified id|title|alt|text in the flat navigation drawer.
*
* @When /^I select "(?P<link_string>(?:[^"]|\\")*)" from flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
* @param string $link
*/
public function i_select_from_flat_navigation_drawer($link) {
$this->i_open_flat_navigation_drawer();
$this->execute('behat_general::i_click_on_in_the', [$link, 'link', '#nav-drawer', 'css_element']);
}
/**
* If we are not on the course main page, click on the course link in the navbar
*/
protected function go_to_main_course_page() {
$url = $this->getSession()->getCurrentUrl();
if (!preg_match('|/course/view.php\?id=[\d]+$|', $url)) {
$this->find('xpath', '//header//div[@id=\'page-navbar\']//a[contains(@href,\'/course/view.php?id=\')]')->click();
$this->execute('behat_general::wait_until_the_page_is_ready');
}
}
/**
* Finds and clicks a link on the admin page (site administration or course administration)
*
* @param array $nodelist
*/
protected function select_on_administration_page($nodelist) {
$parentnodes = $nodelist;
$lastnode = array_pop($parentnodes);
$xpath = '//section[@id=\'region-main\']';
// Check if there is a separate tab for this submenu of the page. If found go to it.
if ($parentnodes) {
$tabname = behat_context_helper::escape($parentnodes[0]);
$tabxpath = '//ul[@role=\'tablist\']/li/a[contains(normalize-space(.), ' . $tabname . ')]';
if ($node = $this->getSession()->getPage()->find('xpath', $tabxpath)) {
if ($this->running_javascript()) {
// Click on the tab and add 'active' tab to the xpath.
$node->click();
$xpath .= '//div[contains(@class,\'active\')]';
} else {
// Add the tab content selector to the xpath.
$tabid = behat_context_helper::escape(ltrim($node->getAttribute('href'), '#'));
$xpath .= '//div[@id = ' . $tabid . ']';
}
array_shift($parentnodes);
}
}
// Find a section with the parent name in it.
if ($parentnodes) {
// Find the section on the page (links may be repeating in different sections).
$section = behat_context_helper::escape($parentnodes[0]);
$xpath .= '//div[@class=\'row\' and contains(.,'.$section.')]';
}
// Find a link and click on it.
$linkname = behat_context_helper::escape($lastnode);
$xpath .= '//a[contains(normalize-space(.), ' . $linkname . ')]';
if (!$node = $this->getSession()->getPage()->find('xpath', $xpath)) {
throw new ElementNotFoundException($this->getSession(), 'Link "' . join(' > ', $nodelist) . '"" not found on the page');
}
$node->click();
$this->wait_for_pending_js();
}
/**
* Locates the administration menu in the <header> element and returns its xpath
*
* @param bool $mustexist if specified throws an exception if menu is not found
* @return null|string
*/
protected function find_header_administration_menu($mustexist = false) {
$menuxpath = '//header[@id=\'page-header\']//div[contains(@class,\'moodle-actionmenu\')]';
if ($mustexist) {
$exception = new ElementNotFoundException($this->getSession(), 'Page header administration menu is not found');
$this->find('xpath', $menuxpath, $exception);
} else if (!$this->getSession()->getPage()->find('xpath', $menuxpath)) {
return null;
}
return $menuxpath;
}
/**
* Locates the administration menu on the page (but not in the header) and returns its xpath
*
* @param bool $mustexist if specified throws an exception if menu is not found
* @return null|string
*/
protected function find_page_administration_menu($mustexist = false) {
$menuxpath = '//div[@id=\'region-main-settings-menu\']';
if ($mustexist) {
$exception = new ElementNotFoundException($this->getSession(), 'Page administration menu is not found');
$this->find('xpath', $menuxpath, $exception);
} else if (!$this->getSession()->getPage()->find('xpath', $menuxpath)) {
return null;
}
return $menuxpath;
}
/**
* Toggles administration menu
*
* @param string $menuxpath (optional) xpath to the page administration menu if already known
*/
protected function toggle_page_administration_menu($menuxpath = null) {
if (!$menuxpath) {
$menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu();
}
if ($menuxpath && $this->running_javascript()) {
$this->find('xpath', $menuxpath . '//a[@data-toggle=\'dropdown\']')->click();
$this->wait_for_pending_js();
}
}
/**
* Finds a page edit cog and select an item from it
*
* If the page edit cog is in the page header and the item is not found there, click "More..." link
* and find the item on the course/frontpage administration page
*
* @param array $nodelist
* @throws ElementNotFoundException
*/
protected function select_from_administration_menu($nodelist) {
// Find administration menu.
if ($menuxpath = $this->find_header_administration_menu()) {
$isheader = true;
} else {
$menuxpath = $this->find_page_administration_menu(true);
$isheader = false;
}
$this->toggle_page_administration_menu($menuxpath);
if (!$isheader || count($nodelist) == 1) {
$lastnode = end($nodelist);
$linkname = behat_context_helper::escape($lastnode);
$link = $this->getSession()->getPage()->find('xpath', $menuxpath . '//a[contains(normalize-space(.), ' . $linkname . ')]');
if ($link) {
$link->click();
$this->wait_for_pending_js();
return;
}
}
if ($isheader) {
// Course administration and Front page administration will have subnodes under "More...".
$linkname = behat_context_helper::escape(get_string('morenavigationlinks'));
$link = $this->getSession()->getPage()->find('xpath', $menuxpath . '//a[contains(normalize-space(.), ' . $linkname . ')]');
if ($link) {
$link->click();
$this->execute('behat_general::wait_until_the_page_is_ready');
$this->select_on_administration_page($nodelist);
return;
}
}
throw new ElementNotFoundException($this->getSession(),
'Link "' . join(' > ', $nodelist) . '" not found in the current page edit menu"');
}
}

View File

@ -254,15 +254,18 @@ class behat_mod_quiz extends behat_question_base {
$editquiz = $this->escape(get_string('editquiz', 'quiz'));
$quizadmin = $this->escape(get_string('pluginadministration', 'quiz'));
$addaquestion = $this->escape(get_string('addaquestion', 'quiz'));
$menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' textmenu')]";
$itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]";
$this->execute('behat_general::click_link', $quizname);
$this->execute("behat_navigation::i_navigate_to_in_current_page_administration", $editquiz);
$this->execute("behat_navigation::i_navigate_to_in_current_page_administration",
$quizadmin . ' > ' . $editquiz);
$this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element"));
$this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element"));
if ($this->running_javascript()) {
$this->execute("behat_action_menu::i_open_the_action_menu_in", array('.slots', "css_element"));
$this->execute("behat_action_menu::i_choose_in_the_open_action_menu", array($addaquestion));
} else {
$this->execute('behat_general::click_link', $addaquestion);
}
$this->finish_adding_question($questiontype, $questiondata);
}
@ -296,9 +299,9 @@ class behat_mod_quiz extends behat_question_base {
}
if ($pageorlast == 'last') {
$xpath = "//div[@class = 'last-add-menu']//a[contains(@class, 'textmenu') and contains(., 'Add')]";
$xpath = "//div[@class = 'last-add-menu']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]";
} else if (preg_match('~Page (\d+)~', $pageorlast, $matches)) {
$xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@class, 'textmenu') and contains(., 'Add')]";
$xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]";
} else {
throw new ExpectationException("The I open the add to quiz menu step must specify either 'Page N' or 'last'.");
}
@ -557,7 +560,7 @@ class behat_mod_quiz extends behat_question_base {
// Split in two checkings to give more feedback in case of exception.
$exception = new ExpectationException('Question "' . $questionnumber . '" is not in section "' .
$sectionheading . '" in the quiz navigation.', $this->getSession());
$xpath = "//div[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " .
$xpath = "//*[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " .
"contains(., {$questionnumberliteral}) and contains(preceding-sibling::h3[1], {$headingliteral})]";
$this->find('xpath', $xpath);
}

View File

@ -55,7 +55,8 @@ class behat_filepicker extends behat_files {
$fieldnode = $this->get_filepicker_node($filemanagerelement);
// Looking for the create folder button inside the specified filemanager.
$exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager', $this->getSession());
$exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager',
$this->getSession());
$newfolder = $this->find('css', 'div.fp-btn-mkdir a', $exception, $fieldnode);
$newfolder->click();
@ -83,8 +84,8 @@ class behat_filepicker extends behat_files {
$fieldnode = $this->get_filepicker_node($filemanagerelement);
$exception = new ExpectationException(
'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager',
$this->getSession()
'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager',
$this->getSession()
);
$folderliteral = behat_context_helper::escape($foldername);
@ -94,22 +95,22 @@ class behat_filepicker extends behat_files {
// In the current folder workspace.
$folder = $this->find(
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" .
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-filename ')]" .
"[normalize-space(.)=$folderliteral]",
$exception,
$fieldnode
$exception,
$fieldnode
);
} catch (ExpectationException $e) {
// And in the pathbar.
$folder = $this->find(
'xpath',
"//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" .
'xpath',
"//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" .
"[normalize-space(.)=$folderliteral]",
$exception,
$fieldnode
$exception,
$fieldnode
);
}
@ -176,7 +177,6 @@ class behat_filepicker extends behat_files {
$okbutton->click();
}
/**
* Makes sure user can see the exact number of elements (files in folders) in the filemanager.
*
@ -190,13 +190,14 @@ class behat_filepicker extends behat_files {
// We count .fp-file elements inside a filemanager not being updated.
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' filemanager ')]" .
"[not(contains(concat(' ', normalize-space(@class), ' '), ' fm-updating '))]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')]";
"[not(contains(concat(' ', normalize-space(@class), ' '), ' fm-updating '))]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')]";
$elements = $this->find_all('xpath', $xpath, false, $filemanagernode);
if (count($elements) != $elementscount) {
throw new ExpectationException('Found '.count($elements).' elements in filemanager instead of expected '.$elementscount, $this->getSession());
throw new ExpectationException('Found '.count($elements).' elements in filemanager. Expected '.$elementscount,
$this->getSession());
}
}
@ -251,7 +252,8 @@ class behat_filepicker extends behat_files {
* @param string $filemanagerelement
* @param TableNode $data Data to fill the form in Select file dialogue
*/
public function i_add_and_overwrite_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement, TableNode $data) {
public function i_add_and_overwrite_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement,
TableNode $data) {
$this->add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, $data,
get_string('overwrite', 'repository'));
}

View File

@ -115,13 +115,14 @@ class behat_repository_upload extends behat_files {
// Ensure all the form is ready.
$noformexception = new ExpectationException('The upload file form is not ready', $this->getSession());
$this->find(
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" .
"[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" .
"/descendant::form",
$noformexception
$noformexception
);
// After this we have the elements we want to interact with.
@ -173,4 +174,37 @@ class behat_repository_upload extends behat_files {
}
/**
* Try to get the filemanager node specified by the element
*
* @param string $filepickerelement
* @return \Behat\Mink\Element\NodeElement
* @throws ExpectationException
*/
protected function get_filepicker_node($filepickerelement) {
// More info about the problem (in case there is a problem).
$exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession());
// If no file picker label is mentioned take the first file picker from the page.
if (empty($filepickerelement)) {
$filepickercontainer = $this->find(
'xpath',
"//*[@class=\"form-filemanager\"]",
$exception
);
} else {
// Gets the filemanager node specified by the locator which contains the filepicker container.
$filepickerelement = behat_context_helper::escape($filepickerelement);
$filepickercontainer = $this->find(
'xpath',
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
"//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' felement ')]",
$exception
);
}
return $filepickercontainer;
}
}

View File

@ -1,97 +0,0 @@
<?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/>.
/**
* Steps definitions related with blocks.
*
* @package core_block
* @category test
* @copyright 2012 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__ . '/../../../../blocks/tests/behat/behat_blocks.php');
/**
* Blocks management steps definitions.
*
* @package core_block
* @category test
* @copyright 2012 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_blocks extends behat_blocks {
public function i_add_the_block($blockname) {
$addblock = get_string('addblock');
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock);
if (!$this->running_javascript()) {
$this->execute('behat_general::i_click_on_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']);
} else {
$this->execute('behat_general::i_click_on_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']);
}
}
public function i_open_the_blocks_action_menu($blockname) {
if (!$this->running_javascript()) {
// Action menu does not need to be open if Javascript is off.
return;
}
// If it is already opened we do nothing.
$blocknode = $this->get_text_selector_node('block', $blockname);
if ($blocknode->hasClass('action-menu-shown')) {
return;
}
$this->execute('behat_general::i_click_on_in_the',
array("a[data-toggle='dropdown']", "css_element", $this->escape($blockname), "block")
);
}
public function the_add_block_selector_should_contain_block($blockname) {
$addblock = get_string('addblock');
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock);
$cancelstr = get_string('cancel');
if (!$this->running_javascript()) {
$this->execute('behat_general::should_exist_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'link_exact', '#region-main', 'css_element']);
} else {
$this->execute('behat_general::should_exist_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'button', $addblock, 'dialogue']);
}
}
public function the_add_block_selector_should_not_contain_block($blockname) {
$addblock = get_string('addblock');
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock);
$cancelstr = get_string('cancel');
if (!$this->running_javascript()) {
$this->execute('behat_general::should_not_exist_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'link_exact', '#region-main', 'css_element']);
} else {
$this->execute('behat_general::should_not_exist_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']);
$this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'button', $addblock, 'dialogue']);
}
}
}

View File

@ -1,323 +0,0 @@
<?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/>.
/**
* Navigation steps overrides.
*
* @copyright 2016 Damyon Wiese
* @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__ . '/../../../../lib/tests/behat/behat_navigation.php');
use Behat\Mink\Exception\ExpectationException as ExpectationException;
use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
/**
* Steps definitions to navigate through the navigation tree nodes (overrides).
*
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_navigation extends behat_navigation {
public function i_follow_in_the_user_menu($nodetext) {
if ($this->running_javascript()) {
// The user menu must be expanded when JS is enabled.
$xpath = "//div[contains(concat(' ', @class, ' '), ' usermenu ')]//a[contains(concat(' ', @class, ' '), ' dropdown-toggle ')]";
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
// Now select the link.
// The CSS path is always present, with or without JS.
$csspath = ".usermenu .dropdown-menu";
$this->execute('behat_general::i_click_on_in_the',
array($nodetext, "link", $csspath, "css_element")
);
}
protected function get_top_navigation_node($nodetext) {
// Avoid problems with quotes.
$nodetextliteral = behat_context_helper::escape($nodetext);
$exception = new ExpectationException('Top navigation node "' . $nodetext . ' not found in "', $this->getSession());
// First find in navigation block.
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' card-text ')]" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/*[contains(normalize-space(.), " . $nodetextliteral .")]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' card-text ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/*[contains(normalize-space(.), " . $nodetextliteral .")]]";
$node = $this->find('xpath', $xpath, $exception);
return $node;
}
/**
* Opens the flat navigation drawer if it is not already open
*
* @When /^I open flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
*/
public function i_open_flat_navigation_drawer() {
if (!$this->running_javascript()) {
// Navigation drawer is always open without JS.
return;
}
$xpath = "//button[contains(@data-action,'toggle-drawer')]";
$node = $this->find('xpath', $xpath);
$expanded = $node->getAttribute('aria-expanded');
if ($expanded === 'false') {
$node->click();
$this->ensure_node_attribute_is_set($node, 'aria-expanded', 'true');
$this->wait_for_pending_js();
}
}
/**
* Closes the flat navigation drawer if it is open (does nothing if JS disabled)
*
* @When /^I close flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
*/
public function i_close_flat_navigation_drawer() {
if (!$this->running_javascript()) {
// Navigation drawer can not be closed without JS.
return;
}
$xpath = "//button[contains(@data-action,'toggle-drawer')]";
$node = $this->find('xpath', $xpath);
$expanded = $node->getAttribute('aria-expanded');
if ($expanded === 'true') {
$node->click();
$this->wait_for_pending_js();
}
}
/**
* Clicks link with specified id|title|alt|text in the flat navigation drawer.
*
* @When /^I select "(?P<link_string>(?:[^"]|\\")*)" from flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
* @param string $link
*/
public function i_select_from_flat_navigation_drawer($link) {
$this->i_open_flat_navigation_drawer();
$this->execute('behat_general::i_click_on_in_the', [$link, 'link', '#nav-drawer', 'css_element']);
}
/**
* If we are not on the course main page, click on the course link in the navbar
*/
protected function go_to_main_course_page() {
$url = $this->getSession()->getCurrentUrl();
if (!preg_match('|/course/view.php\?id=[\d]+$|', $url)) {
$this->find('xpath', '//header//div[@id=\'page-navbar\']//a[contains(@href,\'/course/view.php?id=\')]')->click();
$this->execute('behat_general::wait_until_the_page_is_ready');
}
}
/**
* Finds and clicks a link on the admin page (site administration or course administration)
*
* @param array $nodelist
*/
protected function select_on_administration_page($nodelist) {
$parentnodes = $nodelist;
$lastnode = array_pop($parentnodes);
$xpath = '//section[@id=\'region-main\']';
// Check if there is a separate tab for this submenu of the page. If found go to it.
if ($parentnodes) {
$tabname = behat_context_helper::escape($parentnodes[0]);
$tabxpath = '//ul[@role=\'tablist\']/li/a[contains(normalize-space(.), ' . $tabname . ')]';
if ($node = $this->getSession()->getPage()->find('xpath', $tabxpath)) {
if ($this->running_javascript()) {
// Click on the tab and add 'active' tab to the xpath.
$node->click();
$xpath .= '//div[contains(@class,\'active\')]';
} else {
// Add the tab content selector to the xpath.
$tabid = behat_context_helper::escape(ltrim($node->getAttribute('href'), '#'));
$xpath .= '//div[@id = ' . $tabid . ']';
}
array_shift($parentnodes);
}
}
// Find a section with the parent name in it.
if ($parentnodes) {
// Find the section on the page (links may be repeating in different sections).
$section = behat_context_helper::escape($parentnodes[0]);
$xpath .= '//div[@class=\'row\' and contains(.,'.$section.')]';
}
// Find a link and click on it.
$linkname = behat_context_helper::escape($lastnode);
$xpath .= '//a[contains(normalize-space(.), ' . $linkname . ')]';
if (!$node = $this->getSession()->getPage()->find('xpath', $xpath)) {
throw new ElementNotFoundException($this->getSession(), 'Link "' . join(' > ', $nodelist) . '"" not found on the page');
}
$node->click();
$this->wait_for_pending_js();
}
/**
* Locates the administration menu in the <header> element and returns its xpath
*
* @param bool $mustexist if specified throws an exception if menu is not found
* @return null|string
*/
protected function find_header_administration_menu($mustexist = false) {
$menuxpath = '//header[@id=\'page-header\']//div[contains(@class,\'moodle-actionmenu\')]';
if ($mustexist) {
$exception = new ElementNotFoundException($this->getSession(), 'Page header administration menu is not found');
$this->find('xpath', $menuxpath, $exception);
} else if (!$this->getSession()->getPage()->find('xpath', $menuxpath)) {
return null;
}
return $menuxpath;
}
/**
* Locates the administration menu on the page (but not in the header) and returns its xpath
*
* @param bool $mustexist if specified throws an exception if menu is not found
* @return null|string
*/
protected function find_page_administration_menu($mustexist = false) {
$menuxpath = '//div[@id=\'region-main-settings-menu\']';
if ($mustexist) {
$exception = new ElementNotFoundException($this->getSession(), 'Page administration menu is not found');
$this->find('xpath', $menuxpath, $exception);
} else if (!$this->getSession()->getPage()->find('xpath', $menuxpath)) {
return null;
}
return $menuxpath;
}
/**
* Toggles administration menu
*
* @param string $menuxpath (optional) xpath to the page administration menu if already known
*/
protected function toggle_page_administration_menu($menuxpath = null) {
if (!$menuxpath) {
$menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu();
}
if ($menuxpath && $this->running_javascript()) {
$this->find('xpath', $menuxpath . '//a[@data-toggle=\'dropdown\']')->click();
$this->wait_for_pending_js();
}
}
/**
* Finds a page edit cog and select an item from it
*
* If the page edit cog is in the page header and the item is not found there, click "More..." link
* and find the item on the course/frontpage administration page
*
* @param array $nodelist
* @throws ElementNotFoundException
*/
protected function select_from_administration_menu($nodelist) {
// Find administration menu.
if ($menuxpath = $this->find_header_administration_menu()) {
$isheader = true;
} else {
$menuxpath = $this->find_page_administration_menu(true);
$isheader = false;
}
$this->toggle_page_administration_menu($menuxpath);
if (!$isheader || count($nodelist) == 1) {
$lastnode = end($nodelist);
$linkname = behat_context_helper::escape($lastnode);
$link = $this->getSession()->getPage()->find('xpath', $menuxpath . '//a[contains(normalize-space(.), ' . $linkname . ')]');
if ($link) {
$link->click();
$this->wait_for_pending_js();
return;
}
}
if ($isheader) {
// Course administration and Front page administration will have subnodes under "More...".
$linkname = behat_context_helper::escape(get_string('morenavigationlinks'));
$link = $this->getSession()->getPage()->find('xpath', $menuxpath . '//a[contains(normalize-space(.), ' . $linkname . ')]');
if ($link) {
$link->click();
$this->execute('behat_general::wait_until_the_page_is_ready');
$this->select_on_administration_page($nodelist);
return;
}
}
throw new ElementNotFoundException($this->getSession(),
'Link "' . join(' > ', $nodelist) . '" not found in the current page edit menu"');
}
public function should_exist_in_current_page_administration($element, $selectortype) {
$nodes = array_map('trim', explode('>', $element));
$nodetext = end($nodes);
// Find administration menu.
$menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu(true);
$this->toggle_page_administration_menu($menuxpath);
$this->execute('behat_general::should_exist_in_the', [$nodetext, $selectortype, $menuxpath, 'xpath_element']);
$this->toggle_page_administration_menu($menuxpath);
}
public function should_not_exist_in_current_page_administration($element, $selectortype) {
$nodes = array_map('trim', explode('>', $element));
$nodetext = end($nodes);
// Find administration menu.
$menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu();
if (!$menuxpath) {
// Menu not found, exit.
return;
}
$this->toggle_page_administration_menu($menuxpath);
$this->execute('behat_general::should_not_exist_in_the', [$nodetext, $selectortype, $menuxpath, 'xpath_element']);
$this->toggle_page_administration_menu($menuxpath);
}
public function i_navigate_to_in_current_page_administration($nodetext) {
$nodelist = array_map('trim', explode('>', $nodetext));
$this->select_from_administration_menu($nodelist);
}
public function i_navigate_to_in_site_administration($nodetext) {
$nodelist = array_map('trim', explode('>', $nodetext));
$this->i_select_from_flat_navigation_drawer(get_string('administrationsite'));
$this->select_on_administration_page($nodelist);
}
}

View File

@ -17,7 +17,7 @@
/**
* Steps definitions to open and close action menus (overrides).
*
* @package core
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -30,19 +30,24 @@ require_once(__DIR__ . '/../../../../lib/tests/behat/behat_action_menu.php');
/**
* Steps definitions to open and close action menus (overrides).
*
* @package core
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_action_menu extends behat_action_menu {
class behat_theme_bootstrapbase_behat_action_menu extends behat_action_menu {
public function i_open_the_action_menu_in($element, $selectortype) {
if (!$this->running_javascript()) {
// Action menus automatically expand in a visible list of actions when Javascript is disabled.
return;
}
// Gets the node based on the requested selector type and locator.
$node = $this->get_node_in_container("css_element", "[role=button][aria-haspopup=true]", $selectortype, $element);
$node = $this->get_node_in_container("css_element", "[role=menuitem][aria-haspopup=true]", $selectortype, $element);
// Check if it is not already opened.
if ($node->getAttribute('aria-expanded') === 'true') {
$menunode = $this->find('css', '[aria-labelledby='.$node->getAttribute('id').']');
if ($menunode->getAttribute('aria-hidden') === 'false') {
return;
}
@ -50,13 +55,15 @@ class behat_theme_boost_behat_action_menu extends behat_action_menu {
$node->click();
}
public function i_choose_in_the_open_action_menu($menuitemstring) {
public function i_choose_in_the_open_action_menu($linkstring) {
if (!$this->running_javascript()) {
throw new DriverException('Action menu steps are not available with Javascript disabled');
}
// Gets the node based on the requested selector type and locator.
$menuselector = ".moodle-actionmenu .dropdown.show .dropdown-menu";
$node = $this->get_node_in_container("link", $menuitemstring, "css_element", $menuselector);
$node = $this->get_node_in_container("link",
$linkstring,
"css_element",
".moodle-actionmenu [role=menu][aria-hidden=false]");
$this->ensure_node_is_visible($node);
$node->click();
}

View File

@ -17,6 +17,8 @@
/**
* Steps definitions related with administration overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -32,10 +34,12 @@ use Behat\Gherkin\Node\TableNode as TableNode,
/**
* Site administration level steps definitions overrides.
*
* @copyright 2016 Damyon Wiese
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_admin extends behat_admin {
class behat_theme_bootstrapbase_behat_admin extends behat_admin {
public function i_set_the_following_administration_settings_values(TableNode $table) {
@ -45,12 +49,16 @@ class behat_theme_boost_behat_admin extends behat_admin {
foreach ($data as $label => $value) {
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', [get_string('administrationsite')]);
// We expect admin block to be visible, otherwise go to homepage.
if (!$this->getSession()->getPage()->find('css', '.block_settings')) {
$this->getSession()->visit($this->locate_path('/'));
$this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
}
// Search by label.
$searchbox = $this->find_field(get_string('query', 'admin'));
$searchbox = $this->find_field(get_string('searchinsettings', 'admin'));
$searchbox->setValue($label);
$submitsearch = $this->find('css', 'form input[type=submit][name=search]');
$submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]');
$submitsearch->press();
$this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
@ -64,24 +72,21 @@ class behat_theme_boost_behat_admin extends behat_admin {
// Single element settings.
try {
$fieldxpath = "//*[self::input | self::textarea | self::select]" .
"[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" .
"[@id=//label[contains(normalize-space(.), $label)]/@for or " .
"@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]";
$fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or " .
"./@type = 'hidden')]" . "[@id=//label[contains(normalize-space(.), $label)]/@for or " .
"@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]";
$fieldnode = $this->find('xpath', $fieldxpath, $exception);
$formfieldtypenode = $this->find('xpath', $fieldxpath .
"/ancestor::div[contains(concat(' ', @class, ' '), ' form-setting ')]" .
"/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div");
$formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']" .
"/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div");
} catch (ElementNotFoundException $e) {
// Multi element settings, interacting only the first one.
$fieldxpath = "//*[label[contains(., $label)]|span[contains(., $label)]]" .
"/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
"/descendant::div[contains(concat(' ', @class, ' '), ' form-group ')]" .
"/descendant::*[self::input | self::textarea | self::select]" .
"[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]";
$fieldxpath = "//*[label[normalize-space(.)= $label]|span[normalize-space(.)= $label]]/" .
"ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
"/descendant::div[@class='form-group']/descendant::*[self::input | self::textarea | self::select]" .
"[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]";
$fieldnode = $this->find('xpath', $fieldxpath);
// It is the same one that contains the type.
@ -90,7 +95,6 @@ class behat_theme_boost_behat_admin extends behat_admin {
// Getting the class which contains the field type.
$classes = explode(' ', $formfieldtypenode->getAttribute('class'));
$type = false;
foreach ($classes as $class) {
if (substr($class, 0, 5) == 'form-') {
$type = substr($class, 5);

View File

@ -0,0 +1,79 @@
<?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/>.
/**
* Steps definitions related with blocks.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2012 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__ . '/../../../../blocks/tests/behat/behat_blocks.php');
/**
* Blocks management steps definitions.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2012 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_bootstrapbase_behat_blocks extends behat_blocks {
public function i_add_the_block($blockname) {
$this->execute('behat_forms::i_set_the_field_to',
array("bui_addblock", $this->escape($blockname))
);
// If we are running without javascript we need to submit the form.
if (!$this->running_javascript()) {
$this->execute('behat_general::i_click_on_in_the',
array(get_string('go'), "button", "#add_block", "css_element")
);
}
}
public function i_open_the_blocks_action_menu($blockname) {
if (!$this->running_javascript()) {
// Action menu does not need to be open if Javascript is off.
return;
}
// If it is already opened we do nothing.
$blocknode = $this->get_text_selector_node('block', $blockname);
if ($blocknode->hasClass('action-menu-shown')) {
return;
}
$this->execute('behat_general::i_click_on_in_the',
array(get_string('actions'), "link", $this->escape($blockname), "block")
);
}
public function the_add_block_selector_should_contain_block($blockname) {
$this->execute('behat_forms::the_select_box_should_contain', [get_string('addblock'), $blockname]);
}
public function the_add_block_selector_should_not_contain_block($blockname) {
$this->execute('behat_forms::the_select_box_should_not_contain', [get_string('addblock'), $blockname]);
}
}

View File

@ -17,6 +17,8 @@
/**
* Behat course-related steps definitions overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -33,10 +35,12 @@ use Behat\Gherkin\Node\TableNode as TableNode,
/**
* Course-related steps definitions overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_course extends behat_course {
class behat_theme_bootstrapbase_behat_course extends behat_course {
public function i_open_actions_menu($activityname) {
@ -46,23 +50,15 @@ class behat_theme_boost_behat_course extends behat_course {
// If it is already opened we do nothing.
$activitynode = $this->get_activity_node($activityname);
// Find the menu.
$menunode = $activitynode->find('css', 'a[data-toggle=dropdown]');
if (!$menunode) {
throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname),
$this->getSession());
}
$expanded = $menunode->getAttribute('aria-expanded');
if ($expanded == 'true') {
$classes = array_flip(explode(' ', $activitynode->getAttribute('class')));
if (!empty($classes['action-menu-shown'])) {
return;
}
$this->execute('behat_course::i_click_on_in_the_activity',
array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname))
array("a[role='menuitem']", "css_element", $this->escape($activityname))
);
$this->actions_menu_should_be_open($activityname);
}
public function i_close_actions_menu($activityname) {
@ -73,19 +69,13 @@ class behat_theme_boost_behat_course extends behat_course {
// If it is already closed we do nothing.
$activitynode = $this->get_activity_node($activityname);
// Find the menu.
$menunode = $activitynode->find('css', 'a[data-toggle=dropdown]');
if (!$menunode) {
throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname),
$this->getSession());
}
$expanded = $menunode->getAttribute('aria-expanded');
if ($expanded != 'true') {
$classes = array_flip(explode(' ', $activitynode->getAttribute('class')));
if (empty($classes['action-menu-shown'])) {
return;
}
$this->execute('behat_course::i_click_on_in_the_activity',
array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname))
array("a[role='menuitem']", "css_element", $this->escape($activityname))
);
}
@ -95,16 +85,12 @@ class behat_theme_boost_behat_course extends behat_course {
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);
// Find the menu.
$menunode = $activitynode->find('css', 'a[data-toggle=dropdown]');
if (!$menunode) {
throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname),
$this->getSession());
}
$expanded = $menunode->getAttribute('aria-expanded');
if ($expanded != 'true') {
throw new ExpectationException(sprintf("The action menu for '%s' is not open", $activityname), $this->getSession());
$classes = array_flip(explode(' ', $activitynode->getAttribute('class')));
if (empty($classes['action-menu-shown'])) {
throw new ExpectationException(
sprintf("The action menu for '%s' is not open", $activityname), $this->getSession());
}
}
@ -114,11 +100,11 @@ class behat_theme_boost_behat_course extends behat_course {
// We are on the frontpage.
if ($section) {
// Section 1 represents the contents on the frontpage.
$sectionxpath = "//body[@id='page-site-index']" .
"/descendant::div[contains(concat(' ',normalize-space(@class),' '),' sitetopic ')]";
$sectionxpath = "//body[@id='page-site-index']/descendant::div[contains(concat(' ',normalize-space(@class),' ')," .
"' sitetopic ')]";
} else {
// Section 0 represents "Site main menu" block.
$sectionxpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]";
$sectionxpath = "//div[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]";
}
} else {
// We are inside the course.
@ -130,16 +116,15 @@ class behat_theme_boost_behat_course extends behat_course {
if ($this->running_javascript()) {
// Clicks add activity or resource section link.
$sectionxpath = $sectionxpath . "/descendant::div" .
"[contains(concat(' ', normalize-space(@class) , ' '), ' section-modchooser ')]/span/a";
$sectionxpath = $sectionxpath . "/descendant::div[@class='section-modchooser']/span/a";
$sectionnode = $this->find('xpath', $sectionxpath);
$sectionnode->click();
// Clicks the selected activity if it exists.
$activityxpath = "//div[@id='chooseform']/descendant::label" .
"/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" .
"[normalize-space(.)=$activityliteral]" .
"/parent::label/child::input";
"/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" .
"[normalize-space(.)=$activityliteral]" .
"/parent::label/child::input";
$activitynode = $this->find('xpath', $activityxpath);
$activitynode->doubleClick();
@ -147,9 +132,8 @@ class behat_theme_boost_behat_course extends behat_course {
// Without Javascript.
// Selecting the option from the select box which contains the option.
$selectxpath = $sectionxpath . "/descendant::div" .
"[contains(concat(' ', normalize-space(@class), ' '), ' section_add_menus ')]" .
"/descendant::select[option[normalize-space(.)=$activityliteral]]";
$selectxpath = $sectionxpath . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), " .
"' section_add_menus ')]/descendant::select[option[normalize-space(.)=$activityliteral]]";
$selectnode = $this->find('xpath', $selectxpath);
$selectnode->selectOption($activity);
@ -170,18 +154,18 @@ class behat_theme_boost_behat_course extends behat_course {
// Determine the future new activity xpath from the former one.
$duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" .
"[contains(., $activityliteral)]/following-sibling::li";
$duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@data-toggle='dropdown']";
"[contains(., $activityliteral)]/following-sibling::li";
$duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']";
if ($this->running_javascript()) {
// 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')]";
"[contains(., $activityliteral)]" .
"/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" .
"/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]";
$this->execute("behat_general::wait_until_exists",
array($this->escape($hiddenlightboxxpath), "xpath_element")
array($this->escape($hiddenlightboxxpath), "xpath_element")
);
// Close the original activity actions menu.
@ -190,13 +174,13 @@ class behat_theme_boost_behat_course extends behat_course {
// The next sibling of the former activity will be the duplicated one, so we click on it from it's xpath as, at
// this point, it don't even exists in the DOM (the steps are executed when we return them).
$this->execute('behat_general::i_click_on',
array($this->escape($duplicatedactionsmenuxpath), "xpath_element")
array($this->escape($duplicatedactionsmenuxpath), "xpath_element")
);
}
// We force the xpath as otherwise mink tries to interact with the former one.
$this->execute('behat_general::i_click_on_in_the',
array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element")
array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element")
);
$this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data);
@ -214,7 +198,7 @@ class behat_theme_boost_behat_course extends behat_course {
// If it is already opened we do nothing.
$xpath = $this->section_exists($sectionnumber);
$xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@data-toggle, 'dropdown')]";
$xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@class, 'textmenu')]";
$exception = new ExpectationException('Section "' . $sectionnumber . '" was not found', $this->getSession());
$menu = $this->find('xpath', $xpath, $exception);
@ -235,8 +219,8 @@ class behat_theme_boost_behat_course extends behat_course {
// Edit menu should be visible.
if ($this->is_course_editor()) {
$xpath = $sectionxpath .
"/descendant::div[contains(@class, 'section-actions')]" .
"/descendant::a[contains(@data-toggle, 'dropdown')]";
"/descendant::div[contains(@class, 'section-actions')]" .
"/descendant::a[contains(@class, 'textmenu')]";
if (!$this->getSession()->getPage()->find('xpath', $xpath)) {
throw new ExpectationException('The section edit menu is not available', $this->getSession());
}
@ -244,8 +228,8 @@ class behat_theme_boost_behat_course extends behat_course {
}
protected function user_clicks_on_management_listing_action($listingtype, $listingnode, $action) {
$actionsnode = $listingnode->find('xpath', "//*" .
"[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]");
$actionsnode = $listingnode->find('xpath',
"//*[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]");
if (!$actionsnode) {
throw new ExpectationException("Could not find the actions for $listingtype", $this->getSession());
}
@ -254,7 +238,7 @@ class behat_theme_boost_behat_course extends behat_course {
throw new ExpectationException("Expected action was not available or not found ($action)", $this->getSession());
}
if ($this->running_javascript() && !$actionnode->isVisible()) {
$actionsnode->find('css', 'a[data-toggle=dropdown]')->click();
$actionsnode->find('css', 'a.toggle-display')->click();
$actionnode = $actionsnode->find('css', '.action-'.$action);
}
$actionnode->click();
@ -263,8 +247,8 @@ class behat_theme_boost_behat_course extends behat_course {
protected function is_course_editor() {
// We don't need to behat_base::spin() here as all is already loaded.
if (!$this->getSession()->getPage()->findLink(get_string('turneditingoff')) &&
!$this->getSession()->getPage()->findLink(get_string('turneditingon'))) {
if (!$this->getSession()->getPage()->findButton(get_string('turneditingoff')) &&
!$this->getSession()->getPage()->findButton(get_string('turneditingon'))) {
return false;
}
@ -272,6 +256,9 @@ class behat_theme_boost_behat_course extends behat_course {
}
public function i_navigate_to_course_participants() {
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('participants'));
$coursestr = behat_context_helper::escape(get_string('courses'));
$mycoursestr = behat_context_helper::escape(get_string('mycourses'));
$xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]";
$this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']);
}
}

View File

@ -17,6 +17,8 @@
/**
* Deprecated steps overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2018 Victor Deniz
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -28,16 +30,18 @@ require_once(__DIR__ . '/../../../../lib/tests/behat/behat_deprecated.php');
/**
* Deprecated behat step definitions.
*
* @package theme_boost
* @package theme_bootstrapbase
* @category test
* @copyright 2018 Victor Deniz
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_deprecated extends behat_deprecated {
class behat_theme_bootstrapbase_behat_deprecated extends behat_deprecated {
/**
* Click link in navigation tree that matches the text in parentnode/s (seperated using greater-than character if more than one)
*
* @Given /^I navigate to "(?P<nodetext_string>(?:[^"]|\\")*)" node in "(?P<parentnodes_string>(?:[^"]|\\")*)"$/
*
* @throws ExpectationException
* @param string $nodetext navigation node to click.
* @param string $parentnodes comma seperated list of parent nodes.
@ -57,34 +61,6 @@ class behat_theme_boost_behat_deprecated extends behat_deprecated {
$this->deprecated_message($alternative);
$parentnodes = array_map('trim', explode('>', $parentnodes));
$nodelist = array_merge($parentnodes, [$nodetext]);
$firstnode = array_shift($nodelist);
if ($firstnode === get_string('administrationsite')) {
$this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer',
array(get_string('administrationsite')));
$this->execute('behat_theme_boost_behat_navigation::select_on_administration_page', array($nodelist));
return;
}
if ($firstnode === get_string('sitepages')) {
if ($nodetext === get_string('calendar', 'calendar')) {
$this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer',
array(($nodetext)));
} else {
// TODO MDL-57120 other links under "Site pages" are not accessible without navigation block.
$this->execute('behat_theme_boost_behat_navigation::select_node_in_navigation',
array($nodetext, $parentnodes));
}
return;
}
if ($firstnode === get_string('courseadministration')) {
// Administration menu is available only on the main course page where settings in Administration
// block (original purpose of the step) are available on every course page.
$this->execute('behat_theme_boost_behat_navigation::go_to_main_course_page', array());
}
$this->execute('behat_theme_boost_behat_navigation::select_from_administration_menu', array($nodelist));
$this->execute('behat_navigation::select_node_in_navigation', array($nodetext, $parentnodes));
}
}

View File

@ -17,13 +17,16 @@
/**
* Filemanager and filepicker manipulation steps definitions overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @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_theme_boost_behat_files.php');
require_once(__DIR__ . '/theme_bootstrapbase_behat_file_helper.php');
require_once(__DIR__ . '/../../../../repository/tests/behat/behat_filepicker.php');
use Behat\Mink\Exception\ExpectationException as ExpectationException,
Behat\Gherkin\Node\TableNode as TableNode;
@ -34,22 +37,13 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException,
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
/**
* Creates a folder with specified name in the current folder and in the specified filemanager field.
*
* @Given /^I create "(?P<foldername_string>(?:[^"]|\\")*)" folder in "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $foldername
* @param string $filemanagerelement
*/
class behat_theme_bootstrapbase_behat_filepicker extends behat_theme_bootstrapbase_behat_files {
public function i_create_folder_in_filemanager($foldername, $filemanagerelement) {
$fieldnode = $this->get_filepicker_node($filemanagerelement);
// Looking for the create folder button inside the specified filemanager.
$exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager',
$this->getSession());
$exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager',$this->getSession());
$newfolder = $this->find('css', 'div.fp-btn-mkdir a', $exception, $fieldnode);
$newfolder->click();
@ -64,21 +58,13 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
$buttonnode->click();
}
/**
* Opens the contents of a filemanager folder. It looks for the folder in the current folder and in the path bar.
*
* @Given /^I open "(?P<foldername_string>(?:[^"]|\\")*)" folder from "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $foldername
* @param string $filemanagerelement
*/
public function i_open_folder_from_filemanager($foldername, $filemanagerelement) {
$fieldnode = $this->get_filepicker_node($filemanagerelement);
$exception = new ExpectationException(
'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager',
$this->getSession()
'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager',
$this->getSession()
);
$folderliteral = behat_context_helper::escape($foldername);
@ -88,22 +74,22 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
// In the current folder workspace.
$folder = $this->find(
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" .
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-filename ')]" .
"[normalize-space(.)=$folderliteral]",
$exception,
$fieldnode
$exception,
$fieldnode
);
} catch (ExpectationException $e) {
// And in the pathbar.
$folder = $this->find(
'xpath',
"//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" .
'xpath',
"//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" .
"[normalize-space(.)=$folderliteral]",
$exception,
$fieldnode
$exception,
$fieldnode
);
}
@ -111,14 +97,6 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
$folder->click();
}
/**
* Unzips the specified file from the specified filemanager field. The zip file has to be visible in the current folder.
*
* @Given /^I unzip "(?P<filename_string>(?:[^"]|\\")*)" file from "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $filename
* @param string $filemanagerelement
*/
public function i_unzip_file_from_filemanager($filename, $filemanagerelement) {
// Open the contextual menu of the filemanager element.
@ -129,14 +107,6 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
$this->perform_on_element('unzip', $exception);
}
/**
* Zips the specified folder from the specified filemanager field. The folder has to be in the current folder.
*
* @Given /^I zip "(?P<filename_string>(?:[^"]|\\")*)" folder from "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $foldername
* @param string $filemanagerelement
*/
public function i_zip_folder_from_filemanager($foldername, $filemanagerelement) {
// Open the contextual menu of the filemanager element.
@ -147,14 +117,6 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
$this->perform_on_element('zip', $exception);
}
/**
* Deletes the specified file or folder from the specified filemanager field.
*
* @Given /^I delete "(?P<file_or_folder_name_string>(?:[^"]|\\")*)" from "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $name
* @param string $filemanagerelement
*/
public function i_delete_file_from_filemanager($name, $filemanagerelement) {
// Open the contextual menu of the filemanager element.
@ -170,99 +132,39 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files {
$okbutton->click();
}
/**
* Makes sure user can see the exact number of elements (files in folders) in the filemanager.
*
* @Then /^I should see "(?P<elementscount_number>\d+)" elements in "(?P<filemanagerelement_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param int $elementscount
* @param string $filemanagerelement
*/
public function i_should_see_elements_in_filemanager($elementscount, $filemanagerelement) {
$filemanagernode = $this->get_filepicker_node($filemanagerelement);
// We count .fp-file elements inside a filemanager not being updated.
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' filemanager ')]" .
"[not(contains(concat(' ', normalize-space(@class), ' '), ' fm-updating '))]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')]";
"[not(contains(concat(' ', normalize-space(@class), ' '), ' fm-updating '))]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')]";
$elements = $this->find_all('xpath', $xpath, false, $filemanagernode);
if (count($elements) != $elementscount) {
throw new ExpectationException('Found '.count($elements).' elements in filemanager. Expected '.$elementscount,
$this->getSession());
throw new ExpectationException('Found '.count($elements).' elements in filemanager instead of expected '.$elementscount, $this->getSession());
}
}
/**
* Picks the file from repository leaving default values in select file dialogue.
*
* @When /^I add "(?P<filepath_string>(?:[^"]|\\")*)" file from "(?P<repository_string>(?:[^"]|\\")*)" to "(?P<filemanagerelement_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath
* @param string $repository
* @param string $filemanagerelement
*/
public function i_add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement) {
$this->add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, new TableNode(array()), false);
}
/**
* Picks the file from repository leaving default values in select file dialogue and confirming to overwrite an existing file.
*
* @When /^I add and overwrite "(?P<filepath_string>(?:[^"]|\\")*)" file from "(?P<repository_string>(?:[^"]|\\")*)" to "(?P<filemanagerelement_string>(?:[^"]|\\")*)" filemanager$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath
* @param string $repository
* @param string $filemanagerelement
*/
public function i_add_and_overwrite_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement) {
$this->add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, new TableNode(array()),
get_string('overwrite', 'repository'));
}
/**
* Picks the file from repository filling the form in Select file dialogue.
*
* @When /^I add "(?P<filepath_string>(?:[^"]|\\")*)" file from "(?P<repository_string>(?:[^"]|\\")*)" to "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager as:$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath
* @param string $repository
* @param string $filemanagerelement
* @param TableNode $data Data to fill the form in Select file dialogue
*/
public function i_add_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement, TableNode $data) {
$this->add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, $data, false);
}
/**
* Picks the file from repository confirming to overwrite an existing file
*
* @When /^I add and overwrite "(?P<filepath_string>(?:[^"]|\\")*)" file from "(?P<repository_string>(?:[^"]|\\")*)" to "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager as:$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath
* @param string $repository
* @param string $filemanagerelement
* @param TableNode $data Data to fill the form in Select file dialogue
*/
public function i_add_and_overwrite_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement,
TableNode $data) {
public function i_add_and_overwrite_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement, TableNode $data) {
$this->add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, $data,
get_string('overwrite', 'repository'));
}
/**
* Picks the file from private files repository
*
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath
* @param string $repository
* @param string $filemanagerelement
* @param TableNode $data Data to fill the form in Select file dialogue
* @param false|string $overwriteaction false if we don't expect that file with the same name already exists,
* or button text in overwrite dialogue ("Overwrite", "Rename to ...", "Cancel")
*/
protected function add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, TableNode $data,
$overwriteaction = false) {
$filemanagernode = $this->get_filepicker_node($filemanagerelement);

View File

@ -17,6 +17,8 @@
/**
* Files interactions with behat overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -31,10 +33,12 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException,
/**
* Files-related actions overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_files extends behat_files {
class behat_theme_bootstrapbase_behat_files extends behat_files {
protected function get_filepicker_node($filepickerelement) {
@ -44,18 +48,18 @@ class behat_theme_boost_behat_files extends behat_files {
// If no file picker label is mentioned take the first file picker from the page.
if (empty($filepickerelement)) {
$filepickercontainer = $this->find(
'xpath',
"//*[@data-fieldtype=\"filemanager\"]",
$exception
'xpath',
"//*[@data-fieldtype=\"filemanager\"]",
$exception
);
} else {
// Gets the ffilemanager node specified by the locator which contains the filepicker container.
$filepickerelement = behat_context_helper::escape($filepickerelement);
$filepickercontainer = $this->find(
'xpath',
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
"//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
$exception
'xpath',
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
'//ancestor::div[@data-fieldtype="filemanager" or @data-fieldtype="filepicker"]',
$exception
);
}

View File

@ -17,6 +17,8 @@
/**
* Behat grade related steps definitions overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -27,25 +29,30 @@ require_once(__DIR__ . '/../../../../grade/tests/behat/behat_grade.php');
use Behat\Gherkin\Node\TableNode as TableNode;
class behat_theme_boost_behat_grade extends behat_grade {
/**
* Behat grade overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_bootstrapbase_behat_grade extends behat_grade {
public function i_set_the_following_settings_for_grade_item($gradeitem, TableNode $data) {
$gradeitem = behat_context_helper::escape($gradeitem);
if ($this->running_javascript()) {
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]";
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_action_menu::i_open_the_action_menu_in",
array("//tr[contains(.,$gradeitem)]",
"xpath_element"));
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
}
$savechanges = get_string('savechanges', 'grades');
$edit = behat_context_helper::escape(get_string('edit') . ' ');
$linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " .
"and starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
$this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data);
@ -57,19 +64,16 @@ class behat_theme_boost_behat_grade extends behat_grade {
$gradeitem = behat_context_helper::escape($gradeitem);
if ($this->running_javascript()) {
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]";
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute("behat_action_menu::i_open_the_action_menu_in",
array("//tr[contains(.,$gradeitem)]",
"xpath_element"));
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
}
// Going to edit calculation.
$savechanges = get_string('savechanges', 'grades');
$edit = behat_context_helper::escape(get_string('editcalculation', 'grades'));
$linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " .
"and starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
// Mapping names to idnumbers.
@ -78,11 +82,10 @@ class behat_theme_boost_behat_grade extends behat_grade {
// This xpath looks for course, categories and items with the provided name.
// Grrr, we can't equal in categoryitem and courseitem because there is a line jump...
$inputxpath = "//input[@class='idnumber'][" .
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" or " .
"parent::li[@class='categoryitem' or @class='courseitem']" .
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" or " .
"parent::li[@class='categoryitem' or @class='courseitem']/parent::ul/parent::li[starts-with(text(),'" .
$gradeitem . "')]]";
$this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber));
}
@ -98,18 +101,17 @@ class behat_theme_boost_behat_grade extends behat_grade {
$gradeitem = behat_context_helper::escape($gradeitem);
if ($this->running_javascript()) {
$xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]";
$xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]" .
"//a[contains(@class,'toggle-display')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$xpath = "//tr[contains(.,$gradecategorytotal)]";
$this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element"));
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
}
// Going to edit calculation.
$savechanges = get_string('savechanges', 'grades');
$edit = behat_context_helper::escape(get_string('editcalculation', 'grades'));
$linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " .
"and starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]";
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
// Mapping names to idnumbers.
@ -118,11 +120,11 @@ class behat_theme_boost_behat_grade extends behat_grade {
// This xpath looks for course, categories and items with the provided name.
// Grrr, we can't equal in categoryitem and courseitem because there is a line jump...
$inputxpath = "//input[@class='idnumber'][" .
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" | " .
"parent::li[@class='categoryitem' | @class='courseitem']" .
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
" | " .
"parent::li[@class='categoryitem' | @class='courseitem']" .
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
"]";
$this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber));
}
@ -138,10 +140,10 @@ class behat_theme_boost_behat_grade extends behat_grade {
if ($this->running_javascript()) {
$gradeitemliteral = behat_context_helper::escape($gradeitem);
$xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]";
$xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]" .
"//a[contains(@class,'toggle-display')]";
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
$xpath = "//tr[contains(.,$gradeitemliteral)]";
$this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element"));
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
}
@ -150,10 +152,11 @@ class behat_theme_boost_behat_grade extends behat_grade {
}
public function i_navigate_to_in_the_course_gradebook($gradepath) {
// If we are not on one of the gradebook pages already, follow "Grades" link in the navigation drawer.
// If we are not on one of the gradebook pages already, follow "Grades" link in the navigation block.
$xpath = '//div[contains(@class,\'grade-navigation\')]';
if (!$this->getSession()->getPage()->findAll('xpath', $xpath)) {
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('grades'));
$this->execute("behat_general::i_click_on_in_the", array(get_string('grades'), 'link',
get_string('pluginname', 'block_navigation'), 'block'));
}
$this->select_in_gradebook_tabs($gradepath);

View File

@ -17,6 +17,8 @@
/**
* Steps definitions related to mod_quiz overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -32,28 +34,27 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException;
/**
* Steps definitions related to mod_quiz overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_mod_quiz extends behat_mod_quiz {
class behat_theme_bootstrapbase_behat_mod_quiz extends behat_mod_quiz {
public function i_add_question_to_the_quiz_with($questiontype, $quizname, TableNode $questiondata) {
$quizname = $this->escape($quizname);
$editquiz = $this->escape(get_string('editquiz', 'quiz'));
$quizadmin = $this->escape(get_string('pluginadministration', 'quiz'));
$addaquestion = $this->escape(get_string('addaquestion', 'quiz'));
$menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' textmenu')]";
$itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]";
$this->execute('behat_general::click_link', $quizname);
$this->execute("behat_navigation::i_navigate_to_in_current_page_administration",
$quizadmin . ' > ' . $editquiz);
$this->execute("behat_navigation::i_navigate_to_in_current_page_administration", $editquiz);
if ($this->running_javascript()) {
$this->execute("behat_action_menu::i_open_the_action_menu_in", array('.slots', "css_element"));
$this->execute("behat_action_menu::i_choose_in_the_open_action_menu", array($addaquestion));
} else {
$this->execute('behat_general::click_link', $addaquestion);
}
$this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element"));
$this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element"));
$this->finish_adding_question($questiontype, $questiondata);
}
@ -67,7 +68,7 @@ class behat_theme_boost_behat_mod_quiz extends behat_mod_quiz {
// Split in two checkings to give more feedback in case of exception.
$exception = new ExpectationException('Question "' . $questionnumber . '" is not in section "' .
$sectionheading . '" in the quiz navigation.', $this->getSession());
$xpath = "//*[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " .
$xpath = "//div[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " .
"contains(., {$questionnumberliteral}) and contains(preceding-sibling::h3[1], {$headingliteral})]";
$this->find('xpath', $xpath);
}
@ -79,9 +80,9 @@ class behat_theme_boost_behat_mod_quiz extends behat_mod_quiz {
}
if ($pageorlast == 'last') {
$xpath = "//div[@class = 'last-add-menu']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]";
$xpath = "//div[@class = 'last-add-menu']//a[contains(@class, 'textmenu') and contains(., 'Add')]";
} else if (preg_match('~Page (\d+)~', $pageorlast, $matches)) {
$xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]";
$xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@class, 'textmenu') and contains(., 'Add')]";
} else {
throw new ExpectationException("The I open the add to quiz menu step must specify either 'Page N' or 'last'.");
}

View File

@ -0,0 +1,140 @@
<?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/>.
/**
* Navigation steps overrides.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @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__ . '/../../../../lib/tests/behat/behat_navigation.php');
use Behat\Mink\Exception\ExpectationException as ExpectationException;
use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
/**
* Steps definitions to navigate through the navigation tree nodes (overrides).
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_bootstrapbase_behat_navigation extends behat_navigation {
public function i_follow_in_the_user_menu($nodetext) {
if ($this->running_javascript()) {
// The user menu must be expanded when JS is enabled.
$xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
// Now select the link.
// The CSS path is always present, with or without JS.
$csspath = ".usermenu [data-rel='menu-content']";
$this->execute('behat_general::i_click_on_in_the',
array($nodetext, "link", $csspath, "css_element")
);
}
protected function get_top_navigation_node($nodetext) {
// Avoid problems with quotes.
$nodetextliteral = behat_context_helper::escape($nodetext);
$exception = new ExpectationException('Top navigation node "' . $nodetext . ' not found in "', $this->getSession());
// First find in navigation block.
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"[span[normalize-space(.)=" . $nodetextliteral ."] or a[normalize-space(.)=" . $nodetextliteral ."]]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" .
"[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/span[normalize-space(.)=" . $nodetextliteral ."]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/span[normalize-space(.)=" . $nodetextliteral ."]]" .
"|" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" .
"/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" .
"/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" .
"/a[normalize-space(.)=" . $nodetextliteral ."]]";
$node = $this->find('xpath', $xpath, $exception);
return $node;
}
public function should_exist_in_current_page_administration($element, $selectortype) {
$parentnodes = array_map('trim', explode('>', $element));
// Find the name of the first category of the administration block tree.
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
$node = $this->find('xpath', $xpath);
array_unshift($parentnodes, $node->getText());
$lastnode = array_pop($parentnodes);
if (!$this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) {
throw new ExpectationException(ucfirst($selectortype) . ' "' . $element .
'" not found in current page administration"', $this->getSession());
}
}
public function should_not_exist_in_current_page_administration($element, $selectortype) {
$parentnodes = array_map('trim', explode('>', $element));
// Find the name of the first category of the administration block tree.
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
$node = $this->find('xpath', $xpath);
array_unshift($parentnodes, $node->getText());
$lastnode = array_pop($parentnodes);
if ($this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) {
throw new ExpectationException(ucfirst($selectortype) . ' "' . $element .
'" found in current page administration"', $this->getSession());
}
}
public function i_navigate_to_in_current_page_administration($nodetext) {
$parentnodes = array_map('trim', explode('>', $nodetext));
// Find the name of the first category of the administration block tree.
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
$node = $this->find('xpath', $xpath);
array_unshift($parentnodes, $node->getText());
$lastnode = array_pop($parentnodes);
$this->select_node_in_navigation($lastnode, $parentnodes);
}
public function i_navigate_to_in_site_administration($nodetext) {
$parentnodes = array_map('trim', explode('>', $nodetext));
array_unshift($parentnodes, get_string('administrationsite'));
$lastnode = array_pop($parentnodes);
$this->select_node_in_navigation($lastnode, $parentnodes);
}
}

View File

@ -17,6 +17,8 @@
/**
* Override definitions for the upload repository type.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -31,36 +33,12 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException,
/**
* Override steps definitions to deal with the upload repository.
*
* @package theme_bootstrapbase
* @category test
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_repository_upload extends behat_repository_upload {
protected function get_filepicker_node($filepickerelement) {
// More info about the problem (in case there is a problem).
$exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession());
// If no file picker label is mentioned take the first file picker from the page.
if (empty($filepickerelement)) {
$filepickercontainer = $this->find(
'xpath',
"//*[@class=\"form-filemanager\"]",
$exception
);
} else {
// Gets the ffilemanager node specified by the locator which contains the filepicker container.
$filepickerelement = behat_context_helper::escape($filepickerelement);
$filepickercontainer = $this->find(
'xpath',
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
"//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' felement ')]",
$exception
);
}
return $filepickercontainer;
}
class behat_theme_bootstrapbase_behat_repository_upload extends behat_repository_upload {
protected function upload_file_to_filemanager($filepath, $filemanagerelement, TableNode $data, $overwriteaction = false) {
global $CFG;
@ -73,14 +51,13 @@ class behat_theme_boost_behat_repository_upload extends behat_repository_upload
// Ensure all the form is ready.
$noformexception = new ExpectationException('The upload file form is not ready', $this->getSession());
$this->find(
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" .
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
"[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" .
"/descendant::form",
$noformexception
$noformexception
);
// After this we have the elements we want to interact with.

View File

@ -0,0 +1,8 @@
{
"features": [
"lib/tests/behat/action_menu.feature",
"course/tests/behat/activities_edit_with_block_dock.feature",
"blocks/tests/behat/hide_blocks.feature",
"blocks/tests/behat/move_blocks.feature"
]
}