diff --git a/admin/tests/behat/behat_admin.php b/admin/tests/behat/behat_admin.php index 73ce5728e20..b2fd07083cf 100644 --- a/admin/tests/behat/behat_admin.php +++ b/admin/tests/behat/behat_admin.php @@ -55,16 +55,12 @@ class behat_admin extends behat_base { foreach ($data as $label => $value) { - // We expect admin block to be visible, otherwise go to homepage. - if (!$this->getSession()->getPage()->find('css', '.block_settings')) { - $this->getSession()->visit($this->locate_path('/')); - $this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS); - } + $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', [get_string('administrationsite')]); // Search by label. - $searchbox = $this->find_field(get_string('searchinsettings', 'admin')); + $searchbox = $this->find_field(get_string('query', 'admin')); $searchbox->setValue($label); - $submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]'); + $submitsearch = $this->find('css', 'form input[type=submit][name=search]'); $submitsearch->press(); $this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS); @@ -78,21 +74,24 @@ class behat_admin extends behat_base { // Single element settings. try { - $fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" . - "[@id=//label[contains(normalize-space(.), $label)]/@for or " . - "@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]"; + $fieldxpath = "//*[self::input | self::textarea | self::select]" . + "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" . + "[@id=//label[contains(normalize-space(.), $label)]/@for or " . + "@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]"; $fieldnode = $this->find('xpath', $fieldxpath, $exception); - $formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']" . - "/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div"); + $formfieldtypenode = $this->find('xpath', $fieldxpath . + "/ancestor::div[contains(concat(' ', @class, ' '), ' form-setting ')]" . + "/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div"); } catch (ElementNotFoundException $e) { // Multi element settings, interacting only the first one. - $fieldxpath = "//*[label[normalize-space(.)= $label]|span[normalize-space(.)= $label]]/" . - "ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" . - "/descendant::div[@class='form-group']/descendant::*[self::input | self::textarea | self::select]" . - "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]"; + $fieldxpath = "//*[label[contains(., $label)]|span[contains(., $label)]]" . + "/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" . + "/descendant::div[contains(concat(' ', @class, ' '), ' form-group ')]" . + "/descendant::*[self::input | self::textarea | self::select]" . + "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]"; $fieldnode = $this->find('xpath', $fieldxpath); // It is the same one that contains the type. @@ -101,6 +100,7 @@ class behat_admin extends behat_base { // Getting the class which contains the field type. $classes = explode(' ', $formfieldtypenode->getAttribute('class')); + $type = false; foreach ($classes as $class) { if (substr($class, 0, 5) == 'form-') { $type = substr($class, 5); diff --git a/blocks/tests/behat/behat_blocks.php b/blocks/tests/behat/behat_blocks.php index b05d84c21b0..5f55ca2b262 100644 --- a/blocks/tests/behat/behat_blocks.php +++ b/blocks/tests/behat/behat_blocks.php @@ -46,15 +46,13 @@ class behat_blocks extends behat_base { * @param string $blockname */ public function i_add_the_block($blockname) { - $this->execute('behat_forms::i_set_the_field_to', - array("bui_addblock", $this->escape($blockname)) - ); + $addblock = get_string('addblock'); + $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock); - // If we are running without javascript we need to submit the form. if (!$this->running_javascript()) { - $this->execute('behat_general::i_click_on_in_the', - array(get_string('go'), "button", "#add_block", "css_element") - ); + $this->execute('behat_general::i_click_on_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']); + } else { + $this->execute('behat_general::i_click_on_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']); } } @@ -108,7 +106,7 @@ class behat_blocks extends behat_base { } $this->execute('behat_general::i_click_on_in_the', - array(get_string('actions'), "link", $this->escape($blockname), "block") + array("a[data-toggle='dropdown']", "css_element", $this->escape($blockname), "block") ); } @@ -137,7 +135,17 @@ class behat_blocks extends behat_base { * @param string $blockname */ public function the_add_block_selector_should_contain_block($blockname) { - $this->execute('behat_forms::the_select_box_should_contain', [get_string('addblock'), $blockname]); + $addblock = get_string('addblock'); + $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock); + + $cancelstr = get_string('cancel'); + if (!$this->running_javascript()) { + $this->execute('behat_general::should_exist_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']); + $this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'link_exact', '#region-main', 'css_element']); + } else { + $this->execute('behat_general::should_exist_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']); + $this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'button', $addblock, 'dialogue']); + } } /** @@ -147,6 +155,16 @@ class behat_blocks extends behat_base { * @param string $blockname */ public function the_add_block_selector_should_not_contain_block($blockname) { - $this->execute('behat_forms::the_select_box_should_not_contain', [get_string('addblock'), $blockname]); + $addblock = get_string('addblock'); + $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', $addblock); + + $cancelstr = get_string('cancel'); + if (!$this->running_javascript()) { + $this->execute('behat_general::should_not_exist_in_the', [$blockname, 'link_exact', '#region-main', 'css_element']); + $this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'link_exact', '#region-main', 'css_element']); + } else { + $this->execute('behat_general::should_not_exist_in_the', [$blockname, 'link_exact', $addblock, 'dialogue']); + $this->execute('behat_general::i_click_on_in_the', [$cancelstr, 'button', $addblock, 'dialogue']); + } } } diff --git a/course/tests/behat/behat_course.php b/course/tests/behat/behat_course.php index 93b88603692..ee06c76f9d7 100644 --- a/course/tests/behat/behat_course.php +++ b/course/tests/behat/behat_course.php @@ -186,10 +186,11 @@ class behat_course extends behat_base { // We are on the frontpage. if ($section) { // Section 1 represents the contents on the frontpage. - $sectionxpath = "//body[@id='page-site-index']/descendant::div[contains(concat(' ',normalize-space(@class),' '),' sitetopic ')]"; + $sectionxpath = "//body[@id='page-site-index']" . + "/descendant::div[contains(concat(' ',normalize-space(@class),' '),' sitetopic ')]"; } else { // Section 0 represents "Site main menu" block. - $sectionxpath = "//div[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]"; + $sectionxpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]"; } } else { // We are inside the course. @@ -201,15 +202,16 @@ class behat_course extends behat_base { if ($this->running_javascript()) { // Clicks add activity or resource section link. - $sectionxpath = $sectionxpath . "/descendant::div[@class='section-modchooser']/span/a"; + $sectionxpath = $sectionxpath . "/descendant::div" . + "[contains(concat(' ', normalize-space(@class) , ' '), ' section-modchooser ')]/span/a"; $sectionnode = $this->find('xpath', $sectionxpath); $sectionnode->click(); // Clicks the selected activity if it exists. $activityxpath = "//div[@id='chooseform']/descendant::label" . - "/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" . - "[normalize-space(.)=$activityliteral]" . - "/parent::label/child::input"; + "/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" . + "[normalize-space(.)=$activityliteral]" . + "/parent::label/child::input"; $activitynode = $this->find('xpath', $activityxpath); $activitynode->doubleClick(); @@ -217,8 +219,9 @@ class behat_course extends behat_base { // Without Javascript. // Selecting the option from the select box which contains the option. - $selectxpath = $sectionxpath . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' section_add_menus ')]" . - "/descendant::select[option[normalize-space(.)=$activityliteral]]"; + $selectxpath = $sectionxpath . "/descendant::div" . + "[contains(concat(' ', normalize-space(@class), ' '), ' section_add_menus ')]" . + "/descendant::select[option[normalize-space(.)=$activityliteral]]"; $selectnode = $this->find('xpath', $selectxpath); $selectnode->selectOption($activity); @@ -230,7 +233,6 @@ class behat_course extends behat_base { } - /** * Opens a section edit menu if it is not already opened. * @@ -248,7 +250,7 @@ class behat_course extends behat_base { // If it is already opened we do nothing. $xpath = $this->section_exists($sectionnumber); - $xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@class, 'textmenu')]"; + $xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@data-toggle, 'dropdown')]"; $exception = new ExpectationException('Section "' . $sectionnumber . '" was not found', $this->getSession()); $menu = $this->find('xpath', $xpath, $exception); @@ -550,8 +552,8 @@ class behat_course extends behat_base { // Edit menu should be visible. if ($this->is_course_editor()) { $xpath = $sectionxpath . - "/descendant::div[contains(@class, 'section-actions')]" . - "/descendant::a[contains(@class, 'textmenu')]"; + "/descendant::div[contains(@class, 'section-actions')]" . + "/descendant::a[contains(@data-toggle, 'dropdown')]"; if (!$this->getSession()->getPage()->find('xpath', $xpath)) { throw new ExpectationException('The section edit menu is not available', $this->getSession()); } @@ -843,15 +845,23 @@ class behat_course extends behat_base { // If it is already opened we do nothing. $activitynode = $this->get_activity_node($activityname); - $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); - if (!empty($classes['action-menu-shown'])) { + + // Find the menu. + $menunode = $activitynode->find('css', 'a[data-toggle=dropdown]'); + if (!$menunode) { + throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname), + $this->getSession()); + } + $expanded = $menunode->getAttribute('aria-expanded'); + if ($expanded == 'true') { return; } $this->execute('behat_course::i_click_on_in_the_activity', - array("a[role='menuitem']", "css_element", $this->escape($activityname)) + array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname)) ); + $this->actions_menu_should_be_open($activityname); } /** @@ -869,13 +879,19 @@ class behat_course extends behat_base { // If it is already closed we do nothing. $activitynode = $this->get_activity_node($activityname); - $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); - if (empty($classes['action-menu-shown'])) { + // Find the menu. + $menunode = $activitynode->find('css', 'a[data-toggle=dropdown]'); + if (!$menunode) { + throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname), + $this->getSession()); + } + $expanded = $menunode->getAttribute('aria-expanded'); + if ($expanded != 'true') { return; } $this->execute('behat_course::i_click_on_in_the_activity', - array("a[role='menuitem']", "css_element", $this->escape($activityname)) + array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname)) ); } @@ -892,10 +908,15 @@ class behat_course extends behat_base { throw new DriverException('Activities actions menu not available when Javascript is disabled'); } - // If it is already closed we do nothing. $activitynode = $this->get_activity_node($activityname); - $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); - if (empty($classes['action-menu-shown'])) { + // Find the menu. + $menunode = $activitynode->find('css', 'a[data-toggle=dropdown]'); + if (!$menunode) { + throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname), + $this->getSession()); + } + $expanded = $menunode->getAttribute('aria-expanded'); + if ($expanded != 'true') { throw new ExpectationException(sprintf("The action menu for '%s' is not open", $activityname), $this->getSession()); } } @@ -1039,18 +1060,18 @@ class behat_course extends behat_base { // Determine the future new activity xpath from the former one. $duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" . - "[contains(., $activityliteral)]/following-sibling::li"; - $duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']"; + "[contains(., $activityliteral)]/following-sibling::li"; + $duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@data-toggle='dropdown']"; if ($this->running_javascript()) { // We wait until the AJAX request finishes and the section is visible again. $hiddenlightboxxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" . - "[contains(., $activityliteral)]" . - "/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" . - "/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]"; + "[contains(., $activityliteral)]" . + "/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" . + "/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]"; $this->execute("behat_general::wait_until_exists", - array($this->escape($hiddenlightboxxpath), "xpath_element") + array($this->escape($hiddenlightboxxpath), "xpath_element") ); // Close the original activity actions menu. @@ -1059,13 +1080,13 @@ class behat_course extends behat_base { // The next sibling of the former activity will be the duplicated one, so we click on it from it's xpath as, at // this point, it don't even exists in the DOM (the steps are executed when we return them). $this->execute('behat_general::i_click_on', - array($this->escape($duplicatedactionsmenuxpath), "xpath_element") + array($this->escape($duplicatedactionsmenuxpath), "xpath_element") ); } // We force the xpath as otherwise mink tries to interact with the former one. $this->execute('behat_general::i_click_on_in_the', - array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element") + array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element") ); $this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data); @@ -1281,8 +1302,8 @@ class behat_course extends behat_base { protected function is_course_editor() { // We don't need to behat_base::spin() here as all is already loaded. - if (!$this->getSession()->getPage()->findButton(get_string('turneditingoff')) && - !$this->getSession()->getPage()->findButton(get_string('turneditingon'))) { + if (!$this->getSession()->getPage()->findLink(get_string('turneditingoff')) && + !$this->getSession()->getPage()->findLink(get_string('turneditingon'))) { return false; } @@ -1842,7 +1863,8 @@ class behat_course extends behat_base { * @throws Behat\Mink\Exception\ExpectationException */ protected function user_clicks_on_management_listing_action($listingtype, $listingnode, $action) { - $actionsnode = $listingnode->find('xpath', "//*[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]"); + $actionsnode = $listingnode->find('xpath', "//*" . + "[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]"); if (!$actionsnode) { throw new ExpectationException("Could not find the actions for $listingtype", $this->getSession()); } @@ -1851,7 +1873,7 @@ class behat_course extends behat_base { throw new ExpectationException("Expected action was not available or not found ($action)", $this->getSession()); } if ($this->running_javascript() && !$actionnode->isVisible()) { - $actionsnode->find('css', 'a.toggle-display')->click(); + $actionsnode->find('css', 'a[data-toggle=dropdown]')->click(); $actionnode = $actionsnode->find('css', '.action-'.$action); } $actionnode->click(); @@ -1874,10 +1896,7 @@ class behat_course extends behat_base { * @Given /^I navigate to course participants$/ */ public function i_navigate_to_course_participants() { - $coursestr = behat_context_helper::escape(get_string('courses')); - $mycoursestr = behat_context_helper::escape(get_string('mycourses')); - $xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]"; - $this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']); + $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('participants')); } /** diff --git a/grade/tests/behat/behat_grade.php b/grade/tests/behat/behat_grade.php index 12e67895bfc..b17c4cda874 100644 --- a/grade/tests/behat/behat_grade.php +++ b/grade/tests/behat/behat_grade.php @@ -76,15 +76,18 @@ class behat_grade extends behat_base { $gradeitem = behat_context_helper::escape($gradeitem); if ($this->running_javascript()) { - $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]"; + $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); + $this->execute("behat_action_menu::i_open_the_action_menu_in", + array("//tr[contains(.,$gradeitem)]", + "xpath_element")); } } $savechanges = get_string('savechanges', 'grades'); $edit = behat_context_helper::escape(get_string('edit') . ' '); - $linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; + $linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " . + "and starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; $this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element")); $this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data); @@ -128,16 +131,19 @@ class behat_grade extends behat_base { $gradeitem = behat_context_helper::escape($gradeitem); if ($this->running_javascript()) { - $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]"; + $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); + $this->execute("behat_action_menu::i_open_the_action_menu_in", + array("//tr[contains(.,$gradeitem)]", + "xpath_element")); } } // Going to edit calculation. $savechanges = get_string('savechanges', 'grades'); $edit = behat_context_helper::escape(get_string('editcalculation', 'grades')); - $linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; + $linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " . + "and starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; $this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element")); // Mapping names to idnumbers. @@ -145,11 +151,12 @@ class behat_grade extends behat_base { foreach ($datahash as $gradeitem => $idnumber) { // This xpath looks for course, categories and items with the provided name. // Grrr, we can't equal in categoryitem and courseitem because there is a line jump... - $inputxpath ="//input[@class='idnumber'][" . - "parent::li[@class='item'][text()='" . $gradeitem . "']" . - " or " . - "parent::li[@class='categoryitem' or @class='courseitem']/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . - "]"; + $inputxpath = "//input[@class='idnumber'][" . + "parent::li[@class='item'][text()='" . $gradeitem . "']" . + " or " . + "parent::li[@class='categoryitem' or @class='courseitem']" . + "/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . + "]"; $this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber)); } @@ -174,17 +181,18 @@ class behat_grade extends behat_base { $gradeitem = behat_context_helper::escape($gradeitem); if ($this->running_javascript()) { - $xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]" . - "//a[contains(@class,'toggle-display')]"; + $xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); + $xpath = "//tr[contains(.,$gradecategorytotal)]"; + $this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element")); } } // Going to edit calculation. $savechanges = get_string('savechanges', 'grades'); $edit = behat_context_helper::escape(get_string('editcalculation', 'grades')); - $linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; + $linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " . + "and starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; $this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element")); // Mapping names to idnumbers. @@ -193,11 +201,11 @@ class behat_grade extends behat_base { // This xpath looks for course, categories and items with the provided name. // Grrr, we can't equal in categoryitem and courseitem because there is a line jump... $inputxpath = "//input[@class='idnumber'][" . - "parent::li[@class='item'][text()='" . $gradeitem . "']" . - " | " . - "parent::li[@class='categoryitem' | @class='courseitem']" . - "/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . - "]"; + "parent::li[@class='item'][text()='" . $gradeitem . "']" . + " | " . + "parent::li[@class='categoryitem' | @class='courseitem']" . + "/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . + "]"; $this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber)); } @@ -221,9 +229,10 @@ class behat_grade extends behat_base { if ($this->running_javascript()) { $gradeitemliteral = behat_context_helper::escape($gradeitem); - $xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]"; + $xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); + $xpath = "//tr[contains(.,$gradeitemliteral)]"; + $this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element")); } } @@ -290,11 +299,10 @@ class behat_grade extends behat_base { * @param string $gradepath */ public function i_navigate_to_in_the_course_gradebook($gradepath) { - // If we are not on one of the gradebook pages already, follow "Grades" link in the navigation block. + // If we are not on one of the gradebook pages already, follow "Grades" link in the navigation drawer. $xpath = '//div[contains(@class,\'grade-navigation\')]'; if (!$this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_general::i_click_on_in_the", array(get_string('grades'), 'link', - get_string('pluginname', 'block_navigation'), 'block')); + $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('grades')); } $this->select_in_gradebook_tabs($gradepath); diff --git a/lib/behat/behat_files.php b/lib/behat/behat_files.php index 43ed54f7ff6..d2cb84b72ac 100644 --- a/lib/behat/behat_files.php +++ b/lib/behat/behat_files.php @@ -58,6 +58,7 @@ class behat_files extends behat_base { * @param string $filepickerelement The filepicker form field label * @return NodeElement The hidden element node. */ + protected function get_filepicker_node($filepickerelement) { // More info about the problem (in case there is a problem). @@ -66,18 +67,18 @@ class behat_files extends behat_base { // If no file picker label is mentioned take the first file picker from the page. if (empty($filepickerelement)) { $filepickercontainer = $this->find( - 'xpath', - "//*[@data-fieldtype=\"filemanager\"]", - $exception + 'xpath', + "//*[@data-fieldtype=\"filemanager\"]", + $exception ); } else { // Gets the ffilemanager node specified by the locator which contains the filepicker container. $filepickerelement = behat_context_helper::escape($filepickerelement); $filepickercontainer = $this->find( - 'xpath', - "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . - '//ancestor::div[@data-fieldtype="filemanager" or @data-fieldtype="filepicker"]', - $exception + 'xpath', + "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . + "//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']", + $exception ); } diff --git a/lib/tests/behat/behat_action_menu.php b/lib/tests/behat/behat_action_menu.php index dca01b7edee..f3055ff4834 100644 --- a/lib/tests/behat/behat_action_menu.php +++ b/lib/tests/behat/behat_action_menu.php @@ -49,16 +49,11 @@ class behat_action_menu extends behat_base { * @return void */ public function i_open_the_action_menu_in($element, $selectortype) { - if (!$this->running_javascript()) { - // Action menus automatically expand in a visible list of actions when Javascript is disabled. - return; - } // Gets the node based on the requested selector type and locator. - $node = $this->get_node_in_container("css_element", "[role=menuitem][aria-haspopup=true]", $selectortype, $element); + $node = $this->get_node_in_container("css_element", "[role=button][aria-haspopup=true]", $selectortype, $element); // Check if it is not already opened. - $menunode = $this->find('css', '[aria-labelledby='.$node->getAttribute('id').']'); - if ($menunode->getAttribute('aria-hidden') === 'false') { + if ($node->getAttribute('aria-expanded') === 'true') { return; } @@ -73,15 +68,13 @@ class behat_action_menu extends behat_base { * @param string $linkstring * @return void */ - public function i_choose_in_the_open_action_menu($linkstring) { + public function i_choose_in_the_open_action_menu($menuitemstring) { if (!$this->running_javascript()) { throw new DriverException('Action menu steps are not available with Javascript disabled'); } // Gets the node based on the requested selector type and locator. - $node = $this->get_node_in_container("link", - $linkstring, - "css_element", - ".moodle-actionmenu [role=menu][aria-hidden=false]"); + $menuselector = ".moodle-actionmenu .dropdown.show .dropdown-menu"; + $node = $this->get_node_in_container("link", $menuitemstring, "css_element", $menuselector); $this->ensure_node_is_visible($node); $node->click(); } diff --git a/lib/tests/behat/behat_deprecated.php b/lib/tests/behat/behat_deprecated.php index 67b3d8ef417..c7a693fdff8 100644 --- a/lib/tests/behat/behat_deprecated.php +++ b/lib/tests/behat/behat_deprecated.php @@ -57,8 +57,6 @@ class behat_deprecated extends behat_base { /** * Click link in navigation tree that matches the text in parentnode/s (seperated using greater-than character if more than one) * - * @Given /^I navigate to "(?P(?:[^"]|\\")*)" node in "(?P(?:[^"]|\\")*)"$/ - * * @throws ExpectationException * @param string $nodetext navigation node to click. * @param string $parentnodes comma seperated list of parent nodes. @@ -78,7 +76,35 @@ class behat_deprecated extends behat_base { $this->deprecated_message($alternative); $parentnodes = array_map('trim', explode('>', $parentnodes)); - $this->execute('behat_navigation::select_node_in_navigation', array($nodetext, $parentnodes)); + $nodelist = array_merge($parentnodes, [$nodetext]); + $firstnode = array_shift($nodelist); + + if ($firstnode === get_string('administrationsite')) { + $this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer', + array(get_string('administrationsite'))); + $this->execute('behat_theme_boost_behat_navigation::select_on_administration_page', array($nodelist)); + return; + } + + if ($firstnode === get_string('sitepages')) { + if ($nodetext === get_string('calendar', 'calendar')) { + $this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer', + array(($nodetext))); + } else { + // TODO MDL-57120 other links under "Site pages" are not accessible without navigation block. + $this->execute('behat_theme_boost_behat_navigation::select_node_in_navigation', + array($nodetext, $parentnodes)); + } + return; + } + + if ($firstnode === get_string('courseadministration')) { + // Administration menu is available only on the main course page where settings in Administration + // block (original purpose of the step) are available on every course page. + $this->execute('behat_theme_boost_behat_navigation::go_to_main_course_page', array()); + } + + $this->execute('behat_theme_boost_behat_navigation::select_from_administration_menu', array($nodelist)); } /** diff --git a/lib/tests/behat/behat_navigation.php b/lib/tests/behat/behat_navigation.php index fc7444c50b3..eeab30e3e7f 100644 --- a/lib/tests/behat/behat_navigation.php +++ b/lib/tests/behat/behat_navigation.php @@ -29,6 +29,7 @@ require_once(__DIR__ . '/../../behat/behat_base.php'); use Behat\Mink\Exception\ExpectationException as ExpectationException; use Behat\Mink\Exception\DriverException as DriverException; +use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException; /** * Steps definitions to navigate through the navigation tree nodes. @@ -150,16 +151,16 @@ class behat_navigation extends behat_base { if ($this->running_javascript()) { // The user menu must be expanded when JS is enabled. - $xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]"; + $xpath = "//div[contains(concat(' ', @class, ' '), ' usermenu ')]//a[contains(concat(' ', @class, ' '), ' dropdown-toggle ')]"; $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); } // Now select the link. // The CSS path is always present, with or without JS. - $csspath = ".usermenu [data-rel='menu-content']"; + $csspath = ".usermenu .dropdown-menu"; $this->execute('behat_general::i_click_on_in_the', - array($nodetext, "link", $csspath, "css_element") + array($nodetext, "link", $csspath, "css_element") ); } @@ -318,29 +319,17 @@ class behat_navigation extends behat_base { $exception = new ExpectationException('Top navigation node "' . $nodetext . ' not found in "', $this->getSession()); // First find in navigation block. - $xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]" . - "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . - "/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . - "/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . - "[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . - "[span[normalize-space(.)=" . $nodetextliteral ."] or a[normalize-space(.)=" . $nodetextliteral ."]]]" . - "|" . - "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" . - "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . - "/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . - "/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . - "[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . - "/span[normalize-space(.)=" . $nodetextliteral ."]]" . - "|" . - "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" . - "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . - "/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . - "/span[normalize-space(.)=" . $nodetextliteral ."]]" . - "|" . - "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" . - "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . - "/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . - "/a[normalize-space(.)=" . $nodetextliteral ."]]"; + $xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' card-text ')]" . + "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . + "/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . + "/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . + "[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . + "/*[contains(normalize-space(.), " . $nodetextliteral .")]]" . + "|" . + "//div[contains(concat(' ', normalize-space(@class), ' '), ' card-text ')]/div" . + "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . + "/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . + "/*[contains(normalize-space(.), " . $nodetextliteral .")]]"; $node = $this->find('xpath', $xpath, $exception); @@ -421,13 +410,8 @@ class behat_navigation extends behat_base { * @return void */ public function i_navigate_to_in_current_page_administration($nodetext) { - $parentnodes = array_map('trim', explode('>', $nodetext)); - // Find the name of the first category of the administration block tree. - $xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span'; - $node = $this->find('xpath', $xpath); - array_unshift($parentnodes, $node->getText()); - $lastnode = array_pop($parentnodes); - $this->select_node_in_navigation($lastnode, $parentnodes); + $nodelist = array_map('trim', explode('>', $nodetext)); + $this->select_from_administration_menu($nodelist); } /** @@ -442,17 +426,15 @@ class behat_navigation extends behat_base { * @return void */ public function should_exist_in_current_page_administration($element, $selectortype) { - $parentnodes = array_map('trim', explode('>', $element)); - // Find the name of the first category of the administration block tree. - $xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span'; - $node = $this->find('xpath', $xpath); - array_unshift($parentnodes, $node->getText()); - $lastnode = array_pop($parentnodes); + $nodes = array_map('trim', explode('>', $element)); + $nodetext = end($nodes); - if (!$this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) { - throw new ExpectationException(ucfirst($selectortype) . ' "' . $element . - '" not found in current page administration"', $this->getSession()); - } + // Find administration menu. + $menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu(true); + + $this->toggle_page_administration_menu($menuxpath); + $this->execute('behat_general::should_exist_in_the', [$nodetext, $selectortype, $menuxpath, 'xpath_element']); + $this->toggle_page_administration_menu($menuxpath); } /** @@ -467,17 +449,19 @@ class behat_navigation extends behat_base { * @return void */ public function should_not_exist_in_current_page_administration($element, $selectortype) { - $parentnodes = array_map('trim', explode('>', $element)); - // Find the name of the first category of the administration block tree. - $xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span'; - $node = $this->find('xpath', $xpath); - array_unshift($parentnodes, $node->getText()); - $lastnode = array_pop($parentnodes); + $nodes = array_map('trim', explode('>', $element)); + $nodetext = end($nodes); - if ($this->find_node_in_navigation($lastnode, $parentnodes, strtolower($selectortype))) { - throw new ExpectationException(ucfirst($selectortype) . ' "' . $element . - '" found in current page administration"', $this->getSession()); + // Find administration menu. + $menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu(); + if (!$menuxpath) { + // Menu not found, exit. + return; } + + $this->toggle_page_administration_menu($menuxpath); + $this->execute('behat_general::should_not_exist_in_the', [$nodetext, $selectortype, $menuxpath, 'xpath_element']); + $this->toggle_page_administration_menu($menuxpath); } /** @@ -490,10 +474,9 @@ class behat_navigation extends behat_base { * @return void */ public function i_navigate_to_in_site_administration($nodetext) { - $parentnodes = array_map('trim', explode('>', $nodetext)); - array_unshift($parentnodes, get_string('administrationsite')); - $lastnode = array_pop($parentnodes); - $this->select_node_in_navigation($lastnode, $parentnodes); + $nodelist = array_map('trim', explode('>', $nodetext)); + $this->i_select_from_flat_navigation_drawer(get_string('administrationsite')); + $this->select_on_administration_page($nodelist); } /** @@ -584,4 +567,209 @@ class behat_navigation extends behat_base { $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", [get_string('turneditingon')]); } } + + /** + * Opens the flat navigation drawer if it is not already open + * + * @When /^I open flat navigation drawer$/ + * @throws ElementNotFoundException Thrown by behat_base::find + */ + public function i_open_flat_navigation_drawer() { + if (!$this->running_javascript()) { + // Navigation drawer is always open without JS. + return; + } + $xpath = "//button[contains(@data-action,'toggle-drawer')]"; + $node = $this->find('xpath', $xpath); + $expanded = $node->getAttribute('aria-expanded'); + if ($expanded === 'false') { + $node->click(); + $this->ensure_node_attribute_is_set($node, 'aria-expanded', 'true'); + $this->wait_for_pending_js(); + } + } + + /** + * Closes the flat navigation drawer if it is open (does nothing if JS disabled) + * + * @When /^I close flat navigation drawer$/ + * @throws ElementNotFoundException Thrown by behat_base::find + */ + public function i_close_flat_navigation_drawer() { + if (!$this->running_javascript()) { + // Navigation drawer can not be closed without JS. + return; + } + $xpath = "//button[contains(@data-action,'toggle-drawer')]"; + $node = $this->find('xpath', $xpath); + $expanded = $node->getAttribute('aria-expanded'); + if ($expanded === 'true') { + $node->click(); + $this->wait_for_pending_js(); + } + } + + /** + * Clicks link with specified id|title|alt|text in the flat navigation drawer. + * + * @When /^I select "(?P(?:[^"]|\\")*)" 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
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"'); + } } diff --git a/mod/quiz/tests/behat/behat_mod_quiz.php b/mod/quiz/tests/behat/behat_mod_quiz.php index 7d5750e8c03..cfa4e459281 100644 --- a/mod/quiz/tests/behat/behat_mod_quiz.php +++ b/mod/quiz/tests/behat/behat_mod_quiz.php @@ -254,15 +254,18 @@ class behat_mod_quiz extends behat_question_base { $editquiz = $this->escape(get_string('editquiz', 'quiz')); $quizadmin = $this->escape(get_string('pluginadministration', 'quiz')); $addaquestion = $this->escape(get_string('addaquestion', 'quiz')); - $menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' textmenu')]"; - $itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]"; $this->execute('behat_general::click_link', $quizname); - $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", $editquiz); + $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", + $quizadmin . ' > ' . $editquiz); - $this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element")); - $this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element")); + if ($this->running_javascript()) { + $this->execute("behat_action_menu::i_open_the_action_menu_in", array('.slots', "css_element")); + $this->execute("behat_action_menu::i_choose_in_the_open_action_menu", array($addaquestion)); + } else { + $this->execute('behat_general::click_link', $addaquestion); + } $this->finish_adding_question($questiontype, $questiondata); } @@ -296,9 +299,9 @@ class behat_mod_quiz extends behat_question_base { } if ($pageorlast == 'last') { - $xpath = "//div[@class = 'last-add-menu']//a[contains(@class, 'textmenu') and contains(., 'Add')]"; + $xpath = "//div[@class = 'last-add-menu']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]"; } else if (preg_match('~Page (\d+)~', $pageorlast, $matches)) { - $xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@class, 'textmenu') and contains(., 'Add')]"; + $xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]"; } else { throw new ExpectationException("The I open the add to quiz menu step must specify either 'Page N' or 'last'."); } @@ -557,7 +560,7 @@ class behat_mod_quiz extends behat_question_base { // Split in two checkings to give more feedback in case of exception. $exception = new ExpectationException('Question "' . $questionnumber . '" is not in section "' . $sectionheading . '" in the quiz navigation.', $this->getSession()); - $xpath = "//div[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " . + $xpath = "//*[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " . "contains(., {$questionnumberliteral}) and contains(preceding-sibling::h3[1], {$headingliteral})]"; $this->find('xpath', $xpath); } diff --git a/repository/tests/behat/behat_filepicker.php b/repository/tests/behat/behat_filepicker.php index a64b5f697ad..42c3d5ee59c 100644 --- a/repository/tests/behat/behat_filepicker.php +++ b/repository/tests/behat/behat_filepicker.php @@ -55,7 +55,8 @@ class behat_filepicker extends behat_files { $fieldnode = $this->get_filepicker_node($filemanagerelement); // Looking for the create folder button inside the specified filemanager. - $exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager', $this->getSession()); + $exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager', + $this->getSession()); $newfolder = $this->find('css', 'div.fp-btn-mkdir a', $exception, $fieldnode); $newfolder->click(); @@ -83,8 +84,8 @@ class behat_filepicker extends behat_files { $fieldnode = $this->get_filepicker_node($filemanagerelement); $exception = new ExpectationException( - 'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager', - $this->getSession() + 'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager', + $this->getSession() ); $folderliteral = behat_context_helper::escape($foldername); @@ -94,22 +95,22 @@ class behat_filepicker extends behat_files { // In the current folder workspace. $folder = $this->find( - 'xpath', - "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" . + 'xpath', + "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-filename ')]" . "[normalize-space(.)=$folderliteral]", - $exception, - $fieldnode + $exception, + $fieldnode ); } catch (ExpectationException $e) { // And in the pathbar. $folder = $this->find( - 'xpath', - "//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" . + 'xpath', + "//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" . "[normalize-space(.)=$folderliteral]", - $exception, - $fieldnode + $exception, + $fieldnode ); } @@ -176,7 +177,6 @@ class behat_filepicker extends behat_files { $okbutton->click(); } - /** * Makes sure user can see the exact number of elements (files in folders) in the filemanager. * @@ -190,13 +190,14 @@ class behat_filepicker extends behat_files { // We count .fp-file elements inside a filemanager not being updated. $xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' filemanager ')]" . - "[not(contains(concat(' ', normalize-space(@class), ' '), ' fm-updating '))]" . - "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" . - "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')]"; + "[not(contains(concat(' ', normalize-space(@class), ' '), ' fm-updating '))]" . + "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" . + "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')]"; $elements = $this->find_all('xpath', $xpath, false, $filemanagernode); if (count($elements) != $elementscount) { - throw new ExpectationException('Found '.count($elements).' elements in filemanager instead of expected '.$elementscount, $this->getSession()); + throw new ExpectationException('Found '.count($elements).' elements in filemanager. Expected '.$elementscount, + $this->getSession()); } } @@ -251,7 +252,8 @@ class behat_filepicker extends behat_files { * @param string $filemanagerelement * @param TableNode $data Data to fill the form in Select file dialogue */ - public function i_add_and_overwrite_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement, TableNode $data) { + public function i_add_and_overwrite_file_from_repository_to_filemanager_as($filepath, $repository, $filemanagerelement, + TableNode $data) { $this->add_file_from_repository_to_filemanager($filepath, $repository, $filemanagerelement, $data, get_string('overwrite', 'repository')); } diff --git a/repository/upload/tests/behat/behat_repository_upload.php b/repository/upload/tests/behat/behat_repository_upload.php index 35d723eff5e..85520677058 100644 --- a/repository/upload/tests/behat/behat_repository_upload.php +++ b/repository/upload/tests/behat/behat_repository_upload.php @@ -115,13 +115,14 @@ class behat_repository_upload extends behat_files { // Ensure all the form is ready. $noformexception = new ExpectationException('The upload file form is not ready', $this->getSession()); $this->find( - 'xpath', - "//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" . + 'xpath', + "//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" . "[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" . + "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" . "/descendant::form", - $noformexception + $noformexception ); // After this we have the elements we want to interact with. @@ -173,4 +174,37 @@ class behat_repository_upload extends behat_files { } + /** + * Try to get the filemanager node specified by the element + * + * @param string $filepickerelement + * @return \Behat\Mink\Element\NodeElement + * @throws ExpectationException + */ + protected function get_filepicker_node($filepickerelement) { + + // More info about the problem (in case there is a problem). + $exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession()); + + // If no file picker label is mentioned take the first file picker from the page. + if (empty($filepickerelement)) { + $filepickercontainer = $this->find( + 'xpath', + "//*[@class=\"form-filemanager\"]", + $exception + ); + } else { + // Gets the filemanager node specified by the locator which contains the filepicker container. + $filepickerelement = behat_context_helper::escape($filepickerelement); + $filepickercontainer = $this->find( + 'xpath', + "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . + "//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' felement ')]", + $exception + ); + } + + return $filepickercontainer; + } + } diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_blocks.php b/theme/boost/tests/behat/behat_theme_boost_behat_blocks.php deleted file mode 100644 index 12ab3f72e03..00000000000 --- a/theme/boost/tests/behat/behat_theme_boost_behat_blocks.php +++ /dev/null @@ -1,97 +0,0 @@ -. - -/** - * 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']); - } - } - -} diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_navigation.php b/theme/boost/tests/behat/behat_theme_boost_behat_navigation.php deleted file mode 100644 index a0b5290a4be..00000000000 --- a/theme/boost/tests/behat/behat_theme_boost_behat_navigation.php +++ /dev/null @@ -1,323 +0,0 @@ -. - -/** - * 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(?:[^"]|\\")*)" 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
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); - } -} diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_action_menu.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_action_menu.php similarity index 71% rename from theme/boost/tests/behat/behat_theme_boost_behat_action_menu.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_action_menu.php index c7e536b628b..1ee9c7232e6 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_action_menu.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_action_menu.php @@ -17,7 +17,7 @@ /** * Steps definitions to open and close action menus (overrides). * - * @package core + * @package theme_bootstrapbase * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -30,19 +30,24 @@ require_once(__DIR__ . '/../../../../lib/tests/behat/behat_action_menu.php'); /** * Steps definitions to open and close action menus (overrides). * - * @package core + * @package theme_bootstrapbase * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_action_menu extends behat_action_menu { +class behat_theme_bootstrapbase_behat_action_menu extends behat_action_menu { public function i_open_the_action_menu_in($element, $selectortype) { + if (!$this->running_javascript()) { + // Action menus automatically expand in a visible list of actions when Javascript is disabled. + return; + } // Gets the node based on the requested selector type and locator. - $node = $this->get_node_in_container("css_element", "[role=button][aria-haspopup=true]", $selectortype, $element); + $node = $this->get_node_in_container("css_element", "[role=menuitem][aria-haspopup=true]", $selectortype, $element); // Check if it is not already opened. - if ($node->getAttribute('aria-expanded') === 'true') { + $menunode = $this->find('css', '[aria-labelledby='.$node->getAttribute('id').']'); + if ($menunode->getAttribute('aria-hidden') === 'false') { return; } @@ -50,13 +55,15 @@ class behat_theme_boost_behat_action_menu extends behat_action_menu { $node->click(); } - public function i_choose_in_the_open_action_menu($menuitemstring) { + public function i_choose_in_the_open_action_menu($linkstring) { if (!$this->running_javascript()) { throw new DriverException('Action menu steps are not available with Javascript disabled'); } // Gets the node based on the requested selector type and locator. - $menuselector = ".moodle-actionmenu .dropdown.show .dropdown-menu"; - $node = $this->get_node_in_container("link", $menuitemstring, "css_element", $menuselector); + $node = $this->get_node_in_container("link", + $linkstring, + "css_element", + ".moodle-actionmenu [role=menu][aria-hidden=false]"); $this->ensure_node_is_visible($node); $node->click(); } diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_admin.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_admin.php similarity index 68% rename from theme/boost/tests/behat/behat_theme_boost_behat_admin.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_admin.php index 21ca9d7088e..19419cef81c 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_admin.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_admin.php @@ -17,6 +17,8 @@ /** * Steps definitions related with administration overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -32,10 +34,12 @@ use Behat\Gherkin\Node\TableNode as TableNode, /** * Site administration level steps definitions overrides. * - * @copyright 2016 Damyon Wiese + * @package theme_bootstrapbase + * @category test + * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_admin extends behat_admin { +class behat_theme_bootstrapbase_behat_admin extends behat_admin { public function i_set_the_following_administration_settings_values(TableNode $table) { @@ -45,12 +49,16 @@ class behat_theme_boost_behat_admin extends behat_admin { foreach ($data as $label => $value) { - $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', [get_string('administrationsite')]); + // We expect admin block to be visible, otherwise go to homepage. + if (!$this->getSession()->getPage()->find('css', '.block_settings')) { + $this->getSession()->visit($this->locate_path('/')); + $this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS); + } // Search by label. - $searchbox = $this->find_field(get_string('query', 'admin')); + $searchbox = $this->find_field(get_string('searchinsettings', 'admin')); $searchbox->setValue($label); - $submitsearch = $this->find('css', 'form input[type=submit][name=search]'); + $submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]'); $submitsearch->press(); $this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS); @@ -64,24 +72,21 @@ class behat_theme_boost_behat_admin extends behat_admin { // Single element settings. try { - $fieldxpath = "//*[self::input | self::textarea | self::select]" . - "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" . - "[@id=//label[contains(normalize-space(.), $label)]/@for or " . - "@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]"; + $fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or " . + "./@type = 'hidden')]" . "[@id=//label[contains(normalize-space(.), $label)]/@for or " . + "@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]"; $fieldnode = $this->find('xpath', $fieldxpath, $exception); - $formfieldtypenode = $this->find('xpath', $fieldxpath . - "/ancestor::div[contains(concat(' ', @class, ' '), ' form-setting ')]" . - "/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div"); + $formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']" . + "/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div"); } catch (ElementNotFoundException $e) { // Multi element settings, interacting only the first one. - $fieldxpath = "//*[label[contains(., $label)]|span[contains(., $label)]]" . - "/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" . - "/descendant::div[contains(concat(' ', @class, ' '), ' form-group ')]" . - "/descendant::*[self::input | self::textarea | self::select]" . - "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]"; + $fieldxpath = "//*[label[normalize-space(.)= $label]|span[normalize-space(.)= $label]]/" . + "ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" . + "/descendant::div[@class='form-group']/descendant::*[self::input | self::textarea | self::select]" . + "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]"; $fieldnode = $this->find('xpath', $fieldxpath); // It is the same one that contains the type. @@ -90,7 +95,6 @@ class behat_theme_boost_behat_admin extends behat_admin { // Getting the class which contains the field type. $classes = explode(' ', $formfieldtypenode->getAttribute('class')); - $type = false; foreach ($classes as $class) { if (substr($class, 0, 5) == 'form-') { $type = substr($class, 5); diff --git a/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_blocks.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_blocks.php new file mode 100644 index 00000000000..51ca29b07fb --- /dev/null +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_blocks.php @@ -0,0 +1,79 @@ +. + +/** + * 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]); + } + +} diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_course.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_course.php similarity index 68% rename from theme/boost/tests/behat/behat_theme_boost_behat_course.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_course.php index 6906b669ea4..595d3f63652 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_course.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_course.php @@ -17,6 +17,8 @@ /** * Behat course-related steps definitions overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -33,10 +35,12 @@ use Behat\Gherkin\Node\TableNode as TableNode, /** * Course-related steps definitions overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_course extends behat_course { +class behat_theme_bootstrapbase_behat_course extends behat_course { public function i_open_actions_menu($activityname) { @@ -46,23 +50,15 @@ class behat_theme_boost_behat_course extends behat_course { // If it is already opened we do nothing. $activitynode = $this->get_activity_node($activityname); - - // Find the menu. - $menunode = $activitynode->find('css', 'a[data-toggle=dropdown]'); - if (!$menunode) { - throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname), - $this->getSession()); - } - $expanded = $menunode->getAttribute('aria-expanded'); - if ($expanded == 'true') { + $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); + if (!empty($classes['action-menu-shown'])) { return; } $this->execute('behat_course::i_click_on_in_the_activity', - array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname)) + array("a[role='menuitem']", "css_element", $this->escape($activityname)) ); - $this->actions_menu_should_be_open($activityname); } public function i_close_actions_menu($activityname) { @@ -73,19 +69,13 @@ class behat_theme_boost_behat_course extends behat_course { // If it is already closed we do nothing. $activitynode = $this->get_activity_node($activityname); - // Find the menu. - $menunode = $activitynode->find('css', 'a[data-toggle=dropdown]'); - if (!$menunode) { - throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname), - $this->getSession()); - } - $expanded = $menunode->getAttribute('aria-expanded'); - if ($expanded != 'true') { + $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); + if (empty($classes['action-menu-shown'])) { return; } $this->execute('behat_course::i_click_on_in_the_activity', - array("a[data-toggle='dropdown']", "css_element", $this->escape($activityname)) + array("a[role='menuitem']", "css_element", $this->escape($activityname)) ); } @@ -95,16 +85,12 @@ class behat_theme_boost_behat_course extends behat_course { throw new DriverException('Activities actions menu not available when Javascript is disabled'); } + // If it is already closed we do nothing. $activitynode = $this->get_activity_node($activityname); - // Find the menu. - $menunode = $activitynode->find('css', 'a[data-toggle=dropdown]'); - if (!$menunode) { - throw new ExpectationException(sprintf('Could not find actions menu for the activity "%s"', $activityname), - $this->getSession()); - } - $expanded = $menunode->getAttribute('aria-expanded'); - if ($expanded != 'true') { - throw new ExpectationException(sprintf("The action menu for '%s' is not open", $activityname), $this->getSession()); + $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); + if (empty($classes['action-menu-shown'])) { + throw new ExpectationException( + sprintf("The action menu for '%s' is not open", $activityname), $this->getSession()); } } @@ -114,11 +100,11 @@ class behat_theme_boost_behat_course extends behat_course { // We are on the frontpage. if ($section) { // Section 1 represents the contents on the frontpage. - $sectionxpath = "//body[@id='page-site-index']" . - "/descendant::div[contains(concat(' ',normalize-space(@class),' '),' sitetopic ')]"; + $sectionxpath = "//body[@id='page-site-index']/descendant::div[contains(concat(' ',normalize-space(@class),' ')," . + "' sitetopic ')]"; } else { // Section 0 represents "Site main menu" block. - $sectionxpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]"; + $sectionxpath = "//div[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]"; } } else { // We are inside the course. @@ -130,16 +116,15 @@ class behat_theme_boost_behat_course extends behat_course { if ($this->running_javascript()) { // Clicks add activity or resource section link. - $sectionxpath = $sectionxpath . "/descendant::div" . - "[contains(concat(' ', normalize-space(@class) , ' '), ' section-modchooser ')]/span/a"; + $sectionxpath = $sectionxpath . "/descendant::div[@class='section-modchooser']/span/a"; $sectionnode = $this->find('xpath', $sectionxpath); $sectionnode->click(); // Clicks the selected activity if it exists. $activityxpath = "//div[@id='chooseform']/descendant::label" . - "/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" . - "[normalize-space(.)=$activityliteral]" . - "/parent::label/child::input"; + "/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" . + "[normalize-space(.)=$activityliteral]" . + "/parent::label/child::input"; $activitynode = $this->find('xpath', $activityxpath); $activitynode->doubleClick(); @@ -147,9 +132,8 @@ class behat_theme_boost_behat_course extends behat_course { // Without Javascript. // Selecting the option from the select box which contains the option. - $selectxpath = $sectionxpath . "/descendant::div" . - "[contains(concat(' ', normalize-space(@class), ' '), ' section_add_menus ')]" . - "/descendant::select[option[normalize-space(.)=$activityliteral]]"; + $selectxpath = $sectionxpath . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), " . + "' section_add_menus ')]/descendant::select[option[normalize-space(.)=$activityliteral]]"; $selectnode = $this->find('xpath', $selectxpath); $selectnode->selectOption($activity); @@ -170,18 +154,18 @@ class behat_theme_boost_behat_course extends behat_course { // Determine the future new activity xpath from the former one. $duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" . - "[contains(., $activityliteral)]/following-sibling::li"; - $duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@data-toggle='dropdown']"; + "[contains(., $activityliteral)]/following-sibling::li"; + $duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']"; if ($this->running_javascript()) { // We wait until the AJAX request finishes and the section is visible again. $hiddenlightboxxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" . - "[contains(., $activityliteral)]" . - "/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" . - "/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]"; + "[contains(., $activityliteral)]" . + "/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" . + "/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]"; $this->execute("behat_general::wait_until_exists", - array($this->escape($hiddenlightboxxpath), "xpath_element") + array($this->escape($hiddenlightboxxpath), "xpath_element") ); // Close the original activity actions menu. @@ -190,13 +174,13 @@ class behat_theme_boost_behat_course extends behat_course { // The next sibling of the former activity will be the duplicated one, so we click on it from it's xpath as, at // this point, it don't even exists in the DOM (the steps are executed when we return them). $this->execute('behat_general::i_click_on', - array($this->escape($duplicatedactionsmenuxpath), "xpath_element") + array($this->escape($duplicatedactionsmenuxpath), "xpath_element") ); } // We force the xpath as otherwise mink tries to interact with the former one. $this->execute('behat_general::i_click_on_in_the', - array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element") + array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element") ); $this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data); @@ -214,7 +198,7 @@ class behat_theme_boost_behat_course extends behat_course { // If it is already opened we do nothing. $xpath = $this->section_exists($sectionnumber); - $xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@data-toggle, 'dropdown')]"; + $xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@class, 'textmenu')]"; $exception = new ExpectationException('Section "' . $sectionnumber . '" was not found', $this->getSession()); $menu = $this->find('xpath', $xpath, $exception); @@ -235,8 +219,8 @@ class behat_theme_boost_behat_course extends behat_course { // Edit menu should be visible. if ($this->is_course_editor()) { $xpath = $sectionxpath . - "/descendant::div[contains(@class, 'section-actions')]" . - "/descendant::a[contains(@data-toggle, 'dropdown')]"; + "/descendant::div[contains(@class, 'section-actions')]" . + "/descendant::a[contains(@class, 'textmenu')]"; if (!$this->getSession()->getPage()->find('xpath', $xpath)) { throw new ExpectationException('The section edit menu is not available', $this->getSession()); } @@ -244,8 +228,8 @@ class behat_theme_boost_behat_course extends behat_course { } protected function user_clicks_on_management_listing_action($listingtype, $listingnode, $action) { - $actionsnode = $listingnode->find('xpath', "//*" . - "[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]"); + $actionsnode = $listingnode->find('xpath', + "//*[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]"); if (!$actionsnode) { throw new ExpectationException("Could not find the actions for $listingtype", $this->getSession()); } @@ -254,7 +238,7 @@ class behat_theme_boost_behat_course extends behat_course { throw new ExpectationException("Expected action was not available or not found ($action)", $this->getSession()); } if ($this->running_javascript() && !$actionnode->isVisible()) { - $actionsnode->find('css', 'a[data-toggle=dropdown]')->click(); + $actionsnode->find('css', 'a.toggle-display')->click(); $actionnode = $actionsnode->find('css', '.action-'.$action); } $actionnode->click(); @@ -263,8 +247,8 @@ class behat_theme_boost_behat_course extends behat_course { protected function is_course_editor() { // We don't need to behat_base::spin() here as all is already loaded. - if (!$this->getSession()->getPage()->findLink(get_string('turneditingoff')) && - !$this->getSession()->getPage()->findLink(get_string('turneditingon'))) { + if (!$this->getSession()->getPage()->findButton(get_string('turneditingoff')) && + !$this->getSession()->getPage()->findButton(get_string('turneditingon'))) { return false; } @@ -272,6 +256,9 @@ class behat_theme_boost_behat_course extends behat_course { } public function i_navigate_to_course_participants() { - $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('participants')); + $coursestr = behat_context_helper::escape(get_string('courses')); + $mycoursestr = behat_context_helper::escape(get_string('mycourses')); + $xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]"; + $this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']); } } diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_deprecated.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_deprecated.php similarity index 59% rename from theme/boost/tests/behat/behat_theme_boost_behat_deprecated.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_deprecated.php index 6ab19139b0d..6f7fc87098a 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_deprecated.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_deprecated.php @@ -17,6 +17,8 @@ /** * Deprecated steps overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2018 Victor Deniz * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -28,16 +30,18 @@ require_once(__DIR__ . '/../../../../lib/tests/behat/behat_deprecated.php'); /** * Deprecated behat step definitions. * - * @package theme_boost + * @package theme_bootstrapbase * @category test * @copyright 2018 Victor Deniz * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_deprecated extends behat_deprecated { +class behat_theme_bootstrapbase_behat_deprecated extends behat_deprecated { /** * Click link in navigation tree that matches the text in parentnode/s (seperated using greater-than character if more than one) * + * @Given /^I navigate to "(?P(?:[^"]|\\")*)" node in "(?P(?:[^"]|\\")*)"$/ + * * @throws ExpectationException * @param string $nodetext navigation node to click. * @param string $parentnodes comma seperated list of parent nodes. @@ -57,34 +61,6 @@ class behat_theme_boost_behat_deprecated extends behat_deprecated { $this->deprecated_message($alternative); $parentnodes = array_map('trim', explode('>', $parentnodes)); - $nodelist = array_merge($parentnodes, [$nodetext]); - $firstnode = array_shift($nodelist); - - if ($firstnode === get_string('administrationsite')) { - $this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer', - array(get_string('administrationsite'))); - $this->execute('behat_theme_boost_behat_navigation::select_on_administration_page', array($nodelist)); - return; - } - - if ($firstnode === get_string('sitepages')) { - if ($nodetext === get_string('calendar', 'calendar')) { - $this->execute('behat_theme_boost_behat_navigation::i_select_from_flat_navigation_drawer', - array(($nodetext))); - } else { - // TODO MDL-57120 other links under "Site pages" are not accessible without navigation block. - $this->execute('behat_theme_boost_behat_navigation::select_node_in_navigation', - array($nodetext, $parentnodes)); - } - return; - } - - if ($firstnode === get_string('courseadministration')) { - // Administration menu is available only on the main course page where settings in Administration - // block (original purpose of the step) are available on every course page. - $this->execute('behat_theme_boost_behat_navigation::go_to_main_course_page', array()); - } - - $this->execute('behat_theme_boost_behat_navigation::select_from_administration_menu', array($nodelist)); + $this->execute('behat_navigation::select_node_in_navigation', array($nodetext, $parentnodes)); } } diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_filepicker.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_filepicker.php similarity index 56% rename from theme/boost/tests/behat/behat_theme_boost_behat_filepicker.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_filepicker.php index facb5cc17b7..3343366cef1 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_filepicker.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_filepicker.php @@ -17,13 +17,16 @@ /** * Filemanager and filepicker manipulation steps definitions overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. -require_once(__DIR__ . '/behat_theme_boost_behat_files.php'); +require_once(__DIR__ . '/theme_bootstrapbase_behat_file_helper.php'); +require_once(__DIR__ . '/../../../../repository/tests/behat/behat_filepicker.php'); use Behat\Mink\Exception\ExpectationException as ExpectationException, Behat\Gherkin\Node\TableNode as TableNode; @@ -34,22 +37,13 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException, * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { - /** - * Creates a folder with specified name in the current folder and in the specified filemanager field. - * - * @Given /^I create "(?P(?:[^"]|\\")*)" folder in "(?P(?:[^"]|\\")*)" filemanager$/ - * @throws ExpectationException Thrown by behat_base::find - * @param string $foldername - * @param string $filemanagerelement - */ +class behat_theme_bootstrapbase_behat_filepicker extends behat_theme_bootstrapbase_behat_files { public function i_create_folder_in_filemanager($foldername, $filemanagerelement) { $fieldnode = $this->get_filepicker_node($filemanagerelement); // Looking for the create folder button inside the specified filemanager. - $exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager', - $this->getSession()); + $exception = new ExpectationException('No folders can be created in "'.$filemanagerelement.'" filemanager',$this->getSession()); $newfolder = $this->find('css', 'div.fp-btn-mkdir a', $exception, $fieldnode); $newfolder->click(); @@ -64,21 +58,13 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { $buttonnode->click(); } - /** - * Opens the contents of a filemanager folder. It looks for the folder in the current folder and in the path bar. - * - * @Given /^I open "(?P(?:[^"]|\\")*)" folder from "(?P(?:[^"]|\\")*)" filemanager$/ - * @throws ExpectationException Thrown by behat_base::find - * @param string $foldername - * @param string $filemanagerelement - */ public function i_open_folder_from_filemanager($foldername, $filemanagerelement) { $fieldnode = $this->get_filepicker_node($filemanagerelement); $exception = new ExpectationException( - 'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager', - $this->getSession() + 'The "'.$foldername.'" folder can not be found in the "'.$filemanagerelement.'" filemanager', + $this->getSession() ); $folderliteral = behat_context_helper::escape($foldername); @@ -88,22 +74,22 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { // In the current folder workspace. $folder = $this->find( - 'xpath', - "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" . + 'xpath', + "//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-folder ')]" . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-filename ')]" . "[normalize-space(.)=$folderliteral]", - $exception, - $fieldnode + $exception, + $fieldnode ); } catch (ExpectationException $e) { // And in the pathbar. $folder = $this->find( - 'xpath', - "//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" . + 'xpath', + "//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-path-folder-name ')]" . "[normalize-space(.)=$folderliteral]", - $exception, - $fieldnode + $exception, + $fieldnode ); } @@ -111,14 +97,6 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { $folder->click(); } - /** - * Unzips the specified file from the specified filemanager field. The zip file has to be visible in the current folder. - * - * @Given /^I unzip "(?P(?:[^"]|\\")*)" file from "(?P(?:[^"]|\\")*)" filemanager$/ - * @throws ExpectationException Thrown by behat_base::find - * @param string $filename - * @param string $filemanagerelement - */ public function i_unzip_file_from_filemanager($filename, $filemanagerelement) { // Open the contextual menu of the filemanager element. @@ -129,14 +107,6 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { $this->perform_on_element('unzip', $exception); } - /** - * Zips the specified folder from the specified filemanager field. The folder has to be in the current folder. - * - * @Given /^I zip "(?P(?:[^"]|\\")*)" folder from "(?P(?:[^"]|\\")*)" filemanager$/ - * @throws ExpectationException Thrown by behat_base::find - * @param string $foldername - * @param string $filemanagerelement - */ public function i_zip_folder_from_filemanager($foldername, $filemanagerelement) { // Open the contextual menu of the filemanager element. @@ -147,14 +117,6 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { $this->perform_on_element('zip', $exception); } - /** - * Deletes the specified file or folder from the specified filemanager field. - * - * @Given /^I delete "(?P(?:[^"]|\\")*)" from "(?P(?:[^"]|\\")*)" filemanager$/ - * @throws ExpectationException Thrown by behat_base::find - * @param string $name - * @param string $filemanagerelement - */ public function i_delete_file_from_filemanager($name, $filemanagerelement) { // Open the contextual menu of the filemanager element. @@ -170,99 +132,39 @@ class behat_theme_boost_behat_filepicker extends behat_theme_boost_behat_files { $okbutton->click(); } - - /** - * Makes sure user can see the exact number of elements (files in folders) in the filemanager. - * - * @Then /^I should see "(?P\d+)" elements in "(?P(?:[^"]|\\")*)" 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(?:[^"]|\\")*)" file from "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)" 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(?:[^"]|\\")*)" file from "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)" 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(?:[^"]|\\")*)" file from "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)" 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(?:[^"]|\\")*)" file from "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)" 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); diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_files.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_files.php similarity index 79% rename from theme/boost/tests/behat/behat_theme_boost_behat_files.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_files.php index 15c8c2a742d..1f07d62e207 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_files.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_files.php @@ -17,6 +17,8 @@ /** * Files interactions with behat overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -31,10 +33,12 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException, /** * Files-related actions overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_files extends behat_files { +class behat_theme_bootstrapbase_behat_files extends behat_files { protected function get_filepicker_node($filepickerelement) { @@ -44,18 +48,18 @@ class behat_theme_boost_behat_files extends behat_files { // If no file picker label is mentioned take the first file picker from the page. if (empty($filepickerelement)) { $filepickercontainer = $this->find( - 'xpath', - "//*[@data-fieldtype=\"filemanager\"]", - $exception + 'xpath', + "//*[@data-fieldtype=\"filemanager\"]", + $exception ); } else { // Gets the ffilemanager node specified by the locator which contains the filepicker container. $filepickerelement = behat_context_helper::escape($filepickerelement); $filepickercontainer = $this->find( - 'xpath', - "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . - "//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']", - $exception + 'xpath', + "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . + '//ancestor::div[@data-fieldtype="filemanager" or @data-fieldtype="filepicker"]', + $exception ); } diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_grade.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_grade.php similarity index 72% rename from theme/boost/tests/behat/behat_theme_boost_behat_grade.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_grade.php index fe803eae3f6..3405fd20574 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_grade.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_grade.php @@ -17,6 +17,8 @@ /** * Behat grade related steps definitions overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -27,25 +29,30 @@ require_once(__DIR__ . '/../../../../grade/tests/behat/behat_grade.php'); use Behat\Gherkin\Node\TableNode as TableNode; -class behat_theme_boost_behat_grade extends behat_grade { +/** + * Behat grade overrides. + * + * @package theme_bootstrapbase + * @category test + * @copyright 2016 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_bootstrapbase_behat_grade extends behat_grade { public function i_set_the_following_settings_for_grade_item($gradeitem, TableNode $data) { $gradeitem = behat_context_helper::escape($gradeitem); if ($this->running_javascript()) { - $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]"; + $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_action_menu::i_open_the_action_menu_in", - array("//tr[contains(.,$gradeitem)]", - "xpath_element")); + $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); } } $savechanges = get_string('savechanges', 'grades'); $edit = behat_context_helper::escape(get_string('edit') . ' '); - $linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " . - "and starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; + $linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; $this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element")); $this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data); @@ -57,19 +64,16 @@ class behat_theme_boost_behat_grade extends behat_grade { $gradeitem = behat_context_helper::escape($gradeitem); if ($this->running_javascript()) { - $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]"; + $xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute("behat_action_menu::i_open_the_action_menu_in", - array("//tr[contains(.,$gradeitem)]", - "xpath_element")); + $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); } } // Going to edit calculation. $savechanges = get_string('savechanges', 'grades'); $edit = behat_context_helper::escape(get_string('editcalculation', 'grades')); - $linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " . - "and starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; + $linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; $this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element")); // Mapping names to idnumbers. @@ -78,11 +82,10 @@ class behat_theme_boost_behat_grade extends behat_grade { // This xpath looks for course, categories and items with the provided name. // Grrr, we can't equal in categoryitem and courseitem because there is a line jump... $inputxpath = "//input[@class='idnumber'][" . - "parent::li[@class='item'][text()='" . $gradeitem . "']" . - " or " . - "parent::li[@class='categoryitem' or @class='courseitem']" . - "/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . - "]"; + "parent::li[@class='item'][text()='" . $gradeitem . "']" . + " or " . + "parent::li[@class='categoryitem' or @class='courseitem']/parent::ul/parent::li[starts-with(text(),'" . + $gradeitem . "')]]"; $this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber)); } @@ -98,18 +101,17 @@ class behat_theme_boost_behat_grade extends behat_grade { $gradeitem = behat_context_helper::escape($gradeitem); if ($this->running_javascript()) { - $xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]"; + $xpath = "//tr[contains(.,$gradecategorytotal)]//*[contains(@class,'moodle-actionmenu')]" . + "//a[contains(@class,'toggle-display')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $xpath = "//tr[contains(.,$gradecategorytotal)]"; - $this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element")); + $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); } } // Going to edit calculation. $savechanges = get_string('savechanges', 'grades'); $edit = behat_context_helper::escape(get_string('editcalculation', 'grades')); - $linkxpath = "//a[./*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') " . - "and starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; + $linkxpath = "//a[./img[starts-with(@title,$edit) and contains(@title,$gradeitem)]]"; $this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element")); // Mapping names to idnumbers. @@ -118,11 +120,11 @@ class behat_theme_boost_behat_grade extends behat_grade { // This xpath looks for course, categories and items with the provided name. // Grrr, we can't equal in categoryitem and courseitem because there is a line jump... $inputxpath = "//input[@class='idnumber'][" . - "parent::li[@class='item'][text()='" . $gradeitem . "']" . - " | " . - "parent::li[@class='categoryitem' | @class='courseitem']" . - "/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . - "]"; + "parent::li[@class='item'][text()='" . $gradeitem . "']" . + " | " . + "parent::li[@class='categoryitem' | @class='courseitem']" . + "/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" . + "]"; $this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber)); } @@ -138,10 +140,10 @@ class behat_theme_boost_behat_grade extends behat_grade { if ($this->running_javascript()) { $gradeitemliteral = behat_context_helper::escape($gradeitem); - $xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]"; + $xpath = "//tr[contains(.,$gradeitemliteral)]//*[contains(@class,'moodle-actionmenu')]" . + "//a[contains(@class,'toggle-display')]"; if ($this->getSession()->getPage()->findAll('xpath', $xpath)) { - $xpath = "//tr[contains(.,$gradeitemliteral)]"; - $this->execute("behat_action_menu::i_open_the_action_menu_in", array($xpath, "xpath_element")); + $this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element")); } } @@ -150,10 +152,11 @@ class behat_theme_boost_behat_grade extends behat_grade { } public function i_navigate_to_in_the_course_gradebook($gradepath) { - // If we are not on one of the gradebook pages already, follow "Grades" link in the navigation drawer. + // If we are not on one of the gradebook pages already, follow "Grades" link in the navigation block. $xpath = '//div[contains(@class,\'grade-navigation\')]'; if (!$this->getSession()->getPage()->findAll('xpath', $xpath)) { - $this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('grades')); + $this->execute("behat_general::i_click_on_in_the", array(get_string('grades'), 'link', + get_string('pluginname', 'block_navigation'), 'block')); } $this->select_in_gradebook_tabs($gradepath); diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_mod_quiz.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_mod_quiz.php similarity index 79% rename from theme/boost/tests/behat/behat_theme_boost_behat_mod_quiz.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_mod_quiz.php index c8b27c0b20a..4496d98f879 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_mod_quiz.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_mod_quiz.php @@ -17,6 +17,8 @@ /** * Steps definitions related to mod_quiz overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -32,28 +34,27 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException; /** * Steps definitions related to mod_quiz overrides. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_mod_quiz extends behat_mod_quiz { +class behat_theme_bootstrapbase_behat_mod_quiz extends behat_mod_quiz { public function i_add_question_to_the_quiz_with($questiontype, $quizname, TableNode $questiondata) { $quizname = $this->escape($quizname); $editquiz = $this->escape(get_string('editquiz', 'quiz')); $quizadmin = $this->escape(get_string('pluginadministration', 'quiz')); $addaquestion = $this->escape(get_string('addaquestion', 'quiz')); + $menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' textmenu')]"; + $itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]"; $this->execute('behat_general::click_link', $quizname); - $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", - $quizadmin . ' > ' . $editquiz); + $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", $editquiz); - if ($this->running_javascript()) { - $this->execute("behat_action_menu::i_open_the_action_menu_in", array('.slots', "css_element")); - $this->execute("behat_action_menu::i_choose_in_the_open_action_menu", array($addaquestion)); - } else { - $this->execute('behat_general::click_link', $addaquestion); - } + $this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element")); + $this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element")); $this->finish_adding_question($questiontype, $questiondata); } @@ -67,7 +68,7 @@ class behat_theme_boost_behat_mod_quiz extends behat_mod_quiz { // Split in two checkings to give more feedback in case of exception. $exception = new ExpectationException('Question "' . $questionnumber . '" is not in section "' . $sectionheading . '" in the quiz navigation.', $this->getSession()); - $xpath = "//*[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " . + $xpath = "//div[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " . "contains(., {$questionnumberliteral}) and contains(preceding-sibling::h3[1], {$headingliteral})]"; $this->find('xpath', $xpath); } @@ -79,9 +80,9 @@ class behat_theme_boost_behat_mod_quiz extends behat_mod_quiz { } if ($pageorlast == 'last') { - $xpath = "//div[@class = 'last-add-menu']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]"; + $xpath = "//div[@class = 'last-add-menu']//a[contains(@class, 'textmenu') and contains(., 'Add')]"; } else if (preg_match('~Page (\d+)~', $pageorlast, $matches)) { - $xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@data-toggle, 'dropdown') and contains(., 'Add')]"; + $xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@class, 'textmenu') and contains(., 'Add')]"; } else { throw new ExpectationException("The I open the add to quiz menu step must specify either 'Page N' or 'last'."); } diff --git a/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_navigation.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_navigation.php new file mode 100644 index 00000000000..6e7e6a53525 --- /dev/null +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_navigation.php @@ -0,0 +1,140 @@ +. + +/** + * 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); + } +} diff --git a/theme/boost/tests/behat/behat_theme_boost_behat_repository_upload.php b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_repository_upload.php similarity index 74% rename from theme/boost/tests/behat/behat_theme_boost_behat_repository_upload.php rename to theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_repository_upload.php index a1b551e5f46..a81bc06e5fc 100644 --- a/theme/boost/tests/behat/behat_theme_boost_behat_repository_upload.php +++ b/theme/bootstrapbase/tests/behat/behat_theme_bootstrapbase_behat_repository_upload.php @@ -17,6 +17,8 @@ /** * Override definitions for the upload repository type. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -31,36 +33,12 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException, /** * Override steps definitions to deal with the upload repository. * + * @package theme_bootstrapbase + * @category test * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_theme_boost_behat_repository_upload extends behat_repository_upload { - - protected function get_filepicker_node($filepickerelement) { - - // More info about the problem (in case there is a problem). - $exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession()); - - // If no file picker label is mentioned take the first file picker from the page. - if (empty($filepickerelement)) { - $filepickercontainer = $this->find( - 'xpath', - "//*[@class=\"form-filemanager\"]", - $exception - ); - } else { - // Gets the ffilemanager node specified by the locator which contains the filepicker container. - $filepickerelement = behat_context_helper::escape($filepickerelement); - $filepickercontainer = $this->find( - 'xpath', - "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . - "//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' felement ')]", - $exception - ); - } - - return $filepickercontainer; - } +class behat_theme_bootstrapbase_behat_repository_upload extends behat_repository_upload { protected function upload_file_to_filemanager($filepath, $filemanagerelement, TableNode $data, $overwriteaction = false) { global $CFG; @@ -73,14 +51,13 @@ class behat_theme_boost_behat_repository_upload extends behat_repository_upload // Ensure all the form is ready. $noformexception = new ExpectationException('The upload file form is not ready', $this->getSession()); $this->find( - 'xpath', - "//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" . + 'xpath', + "//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" . "[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" . - "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" . "/descendant::form", - $noformexception + $noformexception ); // After this we have the elements we want to interact with. diff --git a/theme/bootstrapbase/tests/behat/blacklist.json b/theme/bootstrapbase/tests/behat/blacklist.json new file mode 100644 index 00000000000..1d0c8d840e2 --- /dev/null +++ b/theme/bootstrapbase/tests/behat/blacklist.json @@ -0,0 +1,8 @@ +{ + "features": [ + "lib/tests/behat/action_menu.feature", + "course/tests/behat/activities_edit_with_block_dock.feature", + "blocks/tests/behat/hide_blocks.feature", + "blocks/tests/behat/move_blocks.feature" + ] +}