MDL-58428 theme: Shift templates ready for Bootstrapbase removal
[moodle.git] / theme / bootstrapbase / tests / behat / behat_theme_bootstrapbase_behat_course.php
CommitLineData
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
28require_once(__DIR__ . '/../../../../course/tests/behat/behat_course.php');
29
30use 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 43class 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}