Differences Between: [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. 18 19 require_once (__DIR__ . '/../../../lib/behat/behat_base.php'); 20 21 /** 22 * Behat grade related steps definitions. 23 * 24 * @package core_grades 25 * @copyright 2022 Mathew May <mathew.solutions> 26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 27 */ 28 class behat_grades extends behat_base { 29 30 /** 31 * Return the list of partial named selectors. 32 * 33 * @return array 34 */ 35 public static function get_partial_named_selectors(): array { 36 return [ 37 new behat_component_named_selector( 38 'initials bar', 39 [".//*[contains(concat(' ', @class, ' '), ' initialbar ')]//span[contains(., %locator%)]/parent::div"] 40 ), 41 new behat_component_named_selector( 42 'grade_actions', 43 ["//td[count(//table[@id='user-grades']//th[contains(., %locator%)]/preceding-sibling::th)]//*[@data-type='grade']"] 44 ), 45 new behat_component_named_selector( 46 'gradeitem modal', 47 [".//*[contains(concat(' ', @class, ' '), ' modal ')]"] 48 ), 49 ]; 50 } 51 52 /** 53 * Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'. 54 * 55 * Recognised page names are: 56 * | pagetype | name meaning | description | 57 * | [report] view | Course name | The view page for the specified course and report | 58 * | gradebook setup | Course name | The gradebook setup page for the specified course | 59 * | course grade settings | Course name | The grade settings page | 60 * | outcomes | Course name | The grade outcomes page | 61 * | scales | Course name | The grade scales page | 62 * 63 * @param string $type identifies which type of page this is - for example "Grader > View" 64 * @param string $identifier identifies the particular page - for example "Course name" 65 * @return moodle_url the corresponding URL. 66 */ 67 protected function resolve_page_instance_url(string $type, string $identifier): moodle_url { 68 $type = strtolower($type); 69 if (strpos($type, '>') !== false) { 70 [$pluginname, $type] = explode('>', $type); 71 $pluginname = strtolower(trim($pluginname)); 72 73 // Fetch the list of plugins. 74 $plugins = \core_component::get_plugin_list('gradereport'); 75 76 if (array_key_exists($pluginname, $plugins)) { 77 $plugin = $pluginname; 78 } else { 79 $plugins = array_combine( 80 array_keys($plugins), 81 array_keys($plugins), 82 ); 83 84 // This plugin is not in the list of plugins. Check the pluginname string. 85 $names = array_map(fn($name) => strtolower(get_string('pluginname', "gradereport_{$name}")), $plugins); 86 $result = array_search($pluginname, $names); 87 if ($result === false) { 88 throw new \coding_exception("Unknown plugin '{$pluginname}'"); 89 } 90 $plugin = $result; 91 } 92 } 93 $type = trim($type); 94 95 switch ($type) { 96 case 'view': 97 return new moodle_url( 98 "/grade/report/{$plugin}/index.php", 99 ['id' => $this->get_course_id($identifier)] 100 ); 101 case 'gradebook setup': 102 return new moodle_url( 103 "/grade/edit/tree/index.php", 104 ['id' => $this->get_course_id($identifier)] 105 ); 106 case 'course grade settings': 107 return new moodle_url( 108 "/grade/edit/settings/index.php", 109 ['id' => $this->get_course_id($identifier)] 110 ); 111 case 'outcomes': 112 return new moodle_url( 113 "/grade/edit/outcome/course.php", 114 ['id' => $this->get_course_id($identifier)] 115 ); 116 case 'scales': 117 return new moodle_url( 118 "/grade/edit/scale/index.php", 119 ['id' => $this->get_course_id($identifier)] 120 ); 121 default: 122 throw new \coding_exception( 123 "Unknown page type '$type' for page identifier '$identifier'" 124 ); 125 } 126 } 127 128 /** 129 * Select a given element within a specific container instance. 130 * 131 * @Given /^I select "(?P<input_value>(?:[^"]|\\")*)" in the "(?P<instance>(?:[^"]|\\")*)" "(?P<instance_type>(?:[^"]|\\")*)"$/ 132 * @param string $value The Needle 133 * @param string $element The Haystack to select within 134 * @param string $selectortype What type of haystack we are looking in 135 */ 136 public function i_select_in_the($value, $element, $selectortype) { 137 // Getting the container where the text should be found. 138 $container = $this->get_selected_node($selectortype, $element); 139 if ($this->getSession()->getPage()->find('xpath', './/input[@value="' . $value . '"]')) { 140 $node = $this->find('xpath', './/input[@value="' . $value . '"]', false, $container); 141 $node->click(); 142 } else { 143 $node = $this->find('xpath', './/button[@data-action="' . strtolower($value) . '"]', false, $container); 144 $node->press(); 145 } 146 } 147 148 /** 149 * Gets the grade item id from its name. 150 * 151 * @throws Exception 152 * @param string $itemname Item name 153 * @return int 154 */ 155 protected function get_grade_item_id(string $itemname): int { 156 157 global $DB; 158 159 if ($id = $DB->get_field('grade_items', 'id', ['itemname' => $itemname])) { 160 return $id; 161 } 162 163 // The course total is a special case. 164 if ($itemname === "Course total") { 165 if (!$id = $DB->get_field('grade_items', 'id', ['itemtype' => 'course'])) { 166 throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist'); 167 } 168 return $id; 169 } 170 171 // Find a category with the name. 172 if ($catid = $DB->get_field('grade_categories', 'id', ['fullname' => $itemname])) { 173 if ($id = $DB->get_field('grade_items', 'id', ['iteminstance' => $catid])) { 174 return $id; 175 } 176 } 177 178 throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist'); 179 } 180 181 /** 182 * Gets course grade category id from coursename. 183 * 184 * @throws Exception 185 * @param string $coursename 186 * @return int 187 */ 188 protected function get_course_grade_category_id(string $coursename): int { 189 190 global $DB; 191 192 $sql = "SELECT gc.id 193 FROM {grade_categories} gc 194 LEFT JOIN {course} c 195 ON c.id = gc.courseid 196 WHERE c.fullname = ? 197 AND gc.depth = 1"; 198 199 if ($id = $DB->get_field_sql($sql, [$coursename])) { 200 return $id; 201 } 202 203 throw new Exception('The specified course grade category with course name "' . $coursename . '" does not exist'); 204 } 205 206 /** 207 * Gets grade category id from its name. 208 * 209 * @throws Exception 210 * @param string $categoryname 211 * @return int 212 */ 213 protected function get_grade_category_id(string $categoryname): int { 214 215 global $DB; 216 217 $sql = "SELECT gc.id 218 FROM {grade_categories} gc 219 LEFT JOIN {course} c 220 ON c.id = gc.courseid 221 WHERE gc.fullname = ?"; 222 223 if ($id = $DB->get_field_sql($sql, [$categoryname])) { 224 return $id; 225 } 226 227 throw new Exception('The specified grade category with name "' . $categoryname . '" does not exist'); 228 } 229 230 /** 231 * Clicks on given grade item menu. 232 * 233 * @Given /^I click on grade item menu "([^"]*)" of type "([^"]*)" on "([^"]*)" page$/ 234 * @param string $itemname Item name 235 * @param string $itemtype Item type - grade item, category or course 236 * @param string $page Page - setup or grader 237 * @throws Exception 238 */ 239 public function i_click_on_grade_item_menu(string $itemname, string $itemtype, string $page) { 240 $this->execute("behat_navigation::i_close_block_drawer_if_open"); 241 if ($itemtype == 'gradeitem') { 242 $itemid = $this->get_grade_item_id($itemname); 243 } else if ($itemtype == 'category') { 244 $itemid = $this->get_grade_category_id($itemname); 245 } else if ($itemtype == 'course') { 246 $itemid = $this->get_course_grade_category_id($itemname); 247 } else { 248 throw new Exception('Unknown item type: ' . $itemtype); 249 } 250 251 $xpath = "//table[@id='grade_edit_tree_table']"; 252 253 if (($page == 'grader') || ($page == 'setup')) { 254 if ($page == 'grader') { 255 $xpath = "//table[@id='user-grades']"; 256 } 257 258 if ($itemtype == 'gradeitem') { 259 $xpath .= "//*[@data-type='item'][@data-id='" . $itemid . "']"; 260 } else if (($itemtype == 'category') || ($itemtype == 'course')) { 261 $xpath .= "//*[@data-type='category'][@data-id='" . $itemid . "']"; 262 } else { 263 throw new Exception('Unknown item type: ' . $itemtype); 264 } 265 } else { 266 throw new Exception('Unknown page: ' . $page); 267 } 268 $node = $this->get_selected_node("xpath_element", $this->escape($xpath)); 269 $this->execute_js_on_node($node, '{{ELEMENT}}.scrollIntoView({ block: "center", inline: "center" })'); 270 $this->execute("behat_general::i_click_on", [$this->escape($xpath), "xpath_element"]); 271 } 272 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body