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);
// 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.
// 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);
* @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']);
}
}
}
$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")
);
}
* @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']);
+ }
}
/**
* @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']);
+ }
}
}
// 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.
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();
// 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);
}
-
/**
* Opens a section edit menu if it is not already opened.
*
// 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);
// 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());
}
// 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);
}
/**
// 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))
);
}
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());
}
}
// 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.
// 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);
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;
}
* @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());
}
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();
* @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'));
}
/**
$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);
$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.
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));
}
$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.
// 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));
}
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"));
}
}
* @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);
* @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).
// 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
);
}
* @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;
}
* @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();
}
/**
* 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.
$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));
}
/**
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.
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")
);
}
$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);
* @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);
}
/**
* @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);
}
/**
* @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);
-
- if ($this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) {
- throw new ExpectationException(ucfirst($selectortype) . ' "' . $element .
- '" found in current page administration"', $this->getSession());
+ $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);
}
/**
* @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);
}
/**
$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"');
+ }
}
$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);
}
}
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'.");
}
// 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);
}
$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();
$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);
// 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
);
}
$okbutton->click();
}
-
/**
* Makes sure user can see the exact number of elements (files in folders) in the filemanager.
*
// 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());
}
}
* @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'));
}
// 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.
}
+ /**
+ * 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;
+ }
+
}
+++ /dev/null
-<?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']);
- }
- }
-
-}
+++ /dev/null
-<?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);
- }
-}
/**
* 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
/**
* 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;
}
$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();
}
/**
* 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
*/
/**
* 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) {
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);
// 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.
// 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);
--- /dev/null
+<?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]);
+ }
+
+}
/**
* 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
*/
/**
* 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) {
// 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) {
// 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))
);
}
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());
}
}
// 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.
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();
// 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);
// 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.
// 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);
// 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);
// 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());
}
}
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());
}
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();
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;
}
}
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']);
}
}
/**
* 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
*/
/**
* 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.
$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));
}
}
/**
* 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;
* @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();
$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);
// 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
);
}
$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.
$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.
$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.
$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);
/**
* 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
*/
/**
* 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) {
// 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
);
}
/**
* 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
*/
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);
$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.
// 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));
}
$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.
// 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));
}
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"));
}
}
}
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);
/**
* 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
*/
/**
* 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);
}
// 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);
}
}
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'.");
}
--- /dev/null
+<?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);
+ }
+}
/**
* 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
*/
/**
* 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;
// 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.
--- /dev/null
+{
+ "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"
+ ]
+}