Commit | Line | Data |
---|---|---|
63e4df60 DW |
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 | /** | |
18 | * Behat course-related steps definitions overrides. | |
19 | * | |
e3652936 MM |
20 | * @package theme_bootstrapbase |
21 | * @category test | |
63e4df60 DW |
22 | * @copyright 2016 Damyon Wiese |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | ||
26 | // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. | |
27 | ||
28 | require_once(__DIR__ . '/../../../../course/tests/behat/behat_course.php'); | |
29 | ||
30 | use Behat\Gherkin\Node\TableNode as TableNode, | |
31 | Behat\Mink\Exception\ExpectationException as ExpectationException, | |
32 | Behat\Mink\Exception\DriverException as DriverException, | |
33 | Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException; | |
34 | ||
35 | /** | |
36 | * Course-related steps definitions overrides. | |
37 | * | |
e3652936 MM |
38 | * @package theme_bootstrapbase |
39 | * @category test | |
63e4df60 DW |
40 | * @copyright 2016 Damyon Wiese |
41 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
42 | */ | |
e3652936 | 43 | class behat_theme_bootstrapbase_behat_course extends behat_course { |
63e4df60 DW |
44 | |
45 | public function i_open_actions_menu($activityname) { | |
46 | ||
47 | if (!$this->running_javascript()) { | |
48 | throw new DriverException('Activities actions menu not available when Javascript is disabled'); | |
49 | } | |
50 | ||
51 | // If it is already opened we do nothing. | |
52 | $activitynode = $this->get_activity_node($activityname); | |
e3652936 MM |
53 | $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); |
54 | if (!empty($classes['action-menu-shown'])) { | |
63e4df60 DW |
55 | return; |
56 | } | |
57 | ||
58 | $this->execute('behat_course::i_click_on_in_the_activity', | |
e3652936 | 59 | array("a[role='menuitem']", "css_element", $this->escape($activityname)) |
63e4df60 DW |
60 | ); |
61 | ||
62 | } | |
63 | ||
64 | public function i_close_actions_menu($activityname) { | |
65 | ||
66 | if (!$this->running_javascript()) { | |
67 | throw new DriverException('Activities actions menu not available when Javascript is disabled'); | |
68 | } | |
69 | ||
70 | // If it is already closed we do nothing. | |
71 | $activitynode = $this->get_activity_node($activityname); | |
e3652936 MM |
72 | $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); |
73 | if (empty($classes['action-menu-shown'])) { | |
63e4df60 DW |
74 | return; |
75 | } | |
76 | ||
77 | $this->execute('behat_course::i_click_on_in_the_activity', | |
e3652936 | 78 | array("a[role='menuitem']", "css_element", $this->escape($activityname)) |
63e4df60 DW |
79 | ); |
80 | } | |
81 | ||
82 | public function actions_menu_should_be_open($activityname) { | |
83 | ||
84 | if (!$this->running_javascript()) { | |
85 | throw new DriverException('Activities actions menu not available when Javascript is disabled'); | |
86 | } | |
87 | ||
e3652936 | 88 | // If it is already closed we do nothing. |
63e4df60 | 89 | $activitynode = $this->get_activity_node($activityname); |
e3652936 MM |
90 | $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); |
91 | if (empty($classes['action-menu-shown'])) { | |
92 | throw new ExpectationException( | |
93 | sprintf("The action menu for '%s' is not open", $activityname), $this->getSession()); | |
63e4df60 DW |
94 | } |
95 | } | |
96 | ||
97 | public function i_add_to_section($activity, $section) { | |
98 | ||
99 | if ($this->getSession()->getPage()->find('css', 'body#page-site-index') && (int)$section <= 1) { | |
100 | // We are on the frontpage. | |
101 | if ($section) { | |
102 | // Section 1 represents the contents on the frontpage. | |
e3652936 MM |
103 | $sectionxpath = "//body[@id='page-site-index']/descendant::div[contains(concat(' ',normalize-space(@class),' ')," . |
104 | "' sitetopic ')]"; | |
63e4df60 DW |
105 | } else { |
106 | // Section 0 represents "Site main menu" block. | |
e3652936 | 107 | $sectionxpath = "//div[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]"; |
63e4df60 DW |
108 | } |
109 | } else { | |
110 | // We are inside the course. | |
111 | $sectionxpath = "//li[@id='section-" . $section . "']"; | |
112 | } | |
113 | ||
114 | $activityliteral = behat_context_helper::escape(ucfirst($activity)); | |
115 | ||
116 | if ($this->running_javascript()) { | |
117 | ||
118 | // Clicks add activity or resource section link. | |
e3652936 | 119 | $sectionxpath = $sectionxpath . "/descendant::div[@class='section-modchooser']/span/a"; |
63e4df60 DW |
120 | $sectionnode = $this->find('xpath', $sectionxpath); |
121 | $sectionnode->click(); | |
122 | ||
123 | // Clicks the selected activity if it exists. | |
124 | $activityxpath = "//div[@id='chooseform']/descendant::label" . | |
e3652936 MM |
125 | "/descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' typename ')]" . |
126 | "[normalize-space(.)=$activityliteral]" . | |
127 | "/parent::label/child::input"; | |
63e4df60 DW |
128 | $activitynode = $this->find('xpath', $activityxpath); |
129 | $activitynode->doubleClick(); | |
130 | ||
131 | } else { | |
132 | // Without Javascript. | |
133 | ||
134 | // Selecting the option from the select box which contains the option. | |
e3652936 MM |
135 | $selectxpath = $sectionxpath . "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), " . |
136 | "' section_add_menus ')]/descendant::select[option[normalize-space(.)=$activityliteral]]"; | |
63e4df60 DW |
137 | $selectnode = $this->find('xpath', $selectxpath); |
138 | $selectnode->selectOption($activity); | |
139 | ||
140 | // Go button. | |
141 | $gobuttonxpath = $selectxpath . "/ancestor::form/descendant::input[@type='submit']"; | |
142 | $gobutton = $this->find('xpath', $gobuttonxpath); | |
143 | $gobutton->click(); | |
144 | } | |
145 | ||
146 | } | |
147 | ||
148 | public function i_duplicate_activity_editing_the_new_copy_with($activityname, TableNode $data) { | |
149 | ||
150 | $activity = $this->escape($activityname); | |
151 | $activityliteral = behat_context_helper::escape($activityname); | |
152 | ||
153 | $this->execute("behat_course::i_duplicate_activity", $activity); | |
154 | ||
155 | // Determine the future new activity xpath from the former one. | |
156 | $duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" . | |
e3652936 MM |
157 | "[contains(., $activityliteral)]/following-sibling::li"; |
158 | $duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']"; | |
63e4df60 DW |
159 | |
160 | if ($this->running_javascript()) { | |
161 | // We wait until the AJAX request finishes and the section is visible again. | |
162 | $hiddenlightboxxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')]" . | |
e3652936 MM |
163 | "[contains(., $activityliteral)]" . |
164 | "/ancestor::li[contains(concat(' ', normalize-space(@class), ' '), ' section ')]" . | |
165 | "/descendant::div[contains(concat(' ', @class, ' '), ' lightbox ')][contains(@style, 'display: none')]"; | |
63e4df60 DW |
166 | |
167 | $this->execute("behat_general::wait_until_exists", | |
e3652936 | 168 | array($this->escape($hiddenlightboxxpath), "xpath_element") |
63e4df60 DW |
169 | ); |
170 | ||
171 | // Close the original activity actions menu. | |
172 | $this->i_close_actions_menu($activity); | |
173 | ||
174 | // The next sibling of the former activity will be the duplicated one, so we click on it from it's xpath as, at | |
175 | // this point, it don't even exists in the DOM (the steps are executed when we return them). | |
176 | $this->execute('behat_general::i_click_on', | |
e3652936 | 177 | array($this->escape($duplicatedactionsmenuxpath), "xpath_element") |
63e4df60 DW |
178 | ); |
179 | } | |
180 | ||
181 | // We force the xpath as otherwise mink tries to interact with the former one. | |
182 | $this->execute('behat_general::i_click_on_in_the', | |
e3652936 | 183 | array(get_string('editsettings'), "link", $this->escape($duplicatedxpath), "xpath_element") |
63e4df60 DW |
184 | ); |
185 | ||
186 | $this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data); | |
187 | $this->execute("behat_forms::press_button", get_string('savechangesandreturntocourse')); | |
188 | ||
189 | } | |
190 | ||
191 | public function i_open_section_edit_menu($sectionnumber) { | |
192 | if (!$this->running_javascript()) { | |
193 | throw new DriverException('Section edit menu not available when Javascript is disabled'); | |
194 | } | |
195 | ||
196 | // Wait for section to be available, before clicking on the menu. | |
197 | $this->i_wait_until_section_is_available($sectionnumber); | |
198 | ||
199 | // If it is already opened we do nothing. | |
200 | $xpath = $this->section_exists($sectionnumber); | |
e3652936 | 201 | $xpath .= "/descendant::div[contains(@class, 'section-actions')]/descendant::a[contains(@class, 'textmenu')]"; |
63e4df60 DW |
202 | |
203 | $exception = new ExpectationException('Section "' . $sectionnumber . '" was not found', $this->getSession()); | |
204 | $menu = $this->find('xpath', $xpath, $exception); | |
205 | $menu->click(); | |
206 | $this->i_wait_until_section_is_available($sectionnumber); | |
207 | } | |
208 | ||
209 | public function section_should_be_visible($sectionnumber) { | |
210 | ||
211 | $sectionxpath = $this->section_exists($sectionnumber); | |
212 | ||
213 | // Section should not be hidden. | |
214 | $xpath = $sectionxpath . "[not(contains(concat(' ', normalize-space(@class), ' '), ' hidden '))]"; | |
215 | if (!$this->getSession()->getPage()->find('xpath', $xpath)) { | |
216 | throw new ExpectationException('The section is hidden', $this->getSession()); | |
217 | } | |
218 | ||
219 | // Edit menu should be visible. | |
220 | if ($this->is_course_editor()) { | |
221 | $xpath = $sectionxpath . | |
e3652936 MM |
222 | "/descendant::div[contains(@class, 'section-actions')]" . |
223 | "/descendant::a[contains(@class, 'textmenu')]"; | |
63e4df60 DW |
224 | if (!$this->getSession()->getPage()->find('xpath', $xpath)) { |
225 | throw new ExpectationException('The section edit menu is not available', $this->getSession()); | |
226 | } | |
227 | } | |
228 | } | |
229 | ||
230 | protected function user_clicks_on_management_listing_action($listingtype, $listingnode, $action) { | |
e3652936 MM |
231 | $actionsnode = $listingnode->find('xpath', |
232 | "//*[contains(concat(' ', normalize-space(@class), ' '), '{$listingtype}-item-actions')]"); | |
63e4df60 DW |
233 | if (!$actionsnode) { |
234 | throw new ExpectationException("Could not find the actions for $listingtype", $this->getSession()); | |
235 | } | |
236 | $actionnode = $actionsnode->find('css', '.action-'.$action); | |
237 | if (!$actionnode) { | |
238 | throw new ExpectationException("Expected action was not available or not found ($action)", $this->getSession()); | |
239 | } | |
240 | if ($this->running_javascript() && !$actionnode->isVisible()) { | |
e3652936 | 241 | $actionsnode->find('css', 'a.toggle-display')->click(); |
63e4df60 DW |
242 | $actionnode = $actionsnode->find('css', '.action-'.$action); |
243 | } | |
244 | $actionnode->click(); | |
245 | } | |
ba5c5083 | 246 | |
ba5c5083 DW |
247 | protected function is_course_editor() { |
248 | ||
249 | // We don't need to behat_base::spin() here as all is already loaded. | |
e3652936 MM |
250 | if (!$this->getSession()->getPage()->findButton(get_string('turneditingoff')) && |
251 | !$this->getSession()->getPage()->findButton(get_string('turneditingon'))) { | |
ba5c5083 DW |
252 | return false; |
253 | } | |
254 | ||
255 | return true; | |
256 | } | |
ebcff7e2 MG |
257 | |
258 | public function i_navigate_to_course_participants() { | |
e3652936 MM |
259 | $coursestr = behat_context_helper::escape(get_string('courses')); |
260 | $mycoursestr = behat_context_helper::escape(get_string('mycourses')); | |
261 | $xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]"; | |
262 | $this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']); | |
ebcff7e2 | 263 | } |
63e4df60 | 264 | } |