03e93ee7d3934a3d1a52dae4e1a80d031a39ffe3
[moodle.git] / grade / report / grader / tests / behat / behat_gradereport_grader.php
1 <?php
2 // This file is part of Stack - http://stack.bham.ac.uk/
3 //
4 // Stack 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 // Stack 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 Stack.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Behat steps definitions for drag and drop onto image.
19  *
20  * @package   gradereport_grader
21  * @category  test
22  * @copyright 2015 Oakland University
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
28 require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
30 use Behat\Behat\Context\Step\Given,
31     Behat\Behat\Context\Step\Then,
32     Behat\Mink\Exception\ExpectationException as ExpectationException,
33     Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
35 /**
36  * Steps definitions related with the drag and drop onto image question type.
37  *
38  * @copyright 2015 Oakland University
39  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  */
41 class behat_gradereport_grader extends behat_base {
42     /**
43      * Click a given user grade cell.
44      *
45      * @Given /^I click on student "([^"]*)" for grade item "([^"]*)"$/
46      * @param string $student
47      * @param string $itemname
48      * @return Given
49      */
50     public function i_click_on_student_and_grade_item($student, $itemname) {
51         $xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
53         return new Given('I click on "' . $this->escape($xpath) . '" "xpath_element"');
54     }
56     /**
57      * Remove focus for a grade value cell.
58      *
59      * @Given /^I click away from student "([^"]*)" and grade item "([^"]*)" value$/
60      * @param string $student
61      * @param string $itemname
62      * @return Given
63      */
64     public function i_click_away_from_student_and_grade_value($student, $itemname) {
65         $xpath = $this->get_student_and_grade_value_selector($student, $itemname);
67         return new Given('I take focus off "' . $this->escape($xpath) . '" "xpath_element"');
68     }
70     /**
71      * Remove focus for a grade value cell.
72      *
73      * @Given /^I click away from student "([^"]*)" and grade item "([^"]*)" feedback$/
74      * @param string $student
75      * @param string $itemname
76      * @return Given
77      */
78     public function i_click_away_from_student_and_grade_feedback($student, $itemname) {
79         $xpath = $this->get_student_and_grade_feedback_selector($student, $itemname);
81         return new Given('I take focus off "' . $this->escape($xpath) . '" "xpath_element"');
82     }
84     /**
85      * Checks grade values with or without a edit box.
86      *
87      * @Then /^the grade for "([^"]*)" in grade item "([^"]*)" should match "([^"]*)"$/
88      * @throws Exception
89      * @throws ElementNotFoundException
90      * @param string $student
91      * @param string $itemname
92      * @param string $value
93      * @return Then
94      */
95     public function the_grade_should_match($student, $itemname, $value) {
96         $xpath = $this->get_student_and_grade_value_selector($student, $itemname);
98         $gradefield = $this->getSession()->getPage()->find('xpath', $xpath);
99         if (!empty($gradefield)) {
100             // Get the field.
101             $fieldtype = behat_field_manager::guess_field_type($gradefield, $this->getSession());
102             if (!$fieldtype) {
103                 throw new Exception('Could not get field type for grade field "' . $itemname . '"');
104             }
105             $field = behat_field_manager::get_field_instance($fieldtype, $gradefield, $this->getSession());
106             if (!$field->matches($value)) {
107                 $fieldvalue = $field->get_value();
108                 throw new ExpectationException(
109                     'The "' . $student . '" and "' . $itemname . '" grade is "' . $fieldvalue . '", "' . $value . '" expected' ,
110                     $this->getSession()
111                 );
112             }
113         } else {
114             // If there isn't a form field, just search for contents.
115             $valueliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($value);
117             $xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
118             $xpath .= "[contains(normalize-space(.)," . $valueliteral . ")]";
120             $node = $this->getSession()->getDriver()->find($xpath);
121             if (empty($node)) {
122                 $locatorexceptionmsg = 'Cell for "' . $student . '" and "' . $itemname . '" with value "' . $value . '"';
123                 throw new ElementNotFoundException($this->getSession(), $locatorexceptionmsg, null, $xpath);
124             }
125         }
126     }
128     /**
129      * Look for a grade editing field.
130      *
131      * @Then /^I should see a grade field for "([^"]*)" and grade item "([^"]*)"$/
132      * @param string $student
133      * @param string $itemname
134      * @return Then
135      */
136     public function i_should_see_grade_field($student, $itemname) {
137         $xpath = $this->get_student_and_grade_value_selector($student, $itemname);
139         return new Then('"' . $this->escape($xpath) . '" "xpath_element" should be visible');
140     }
142     /**
143      * Look for a feedback editing field.
144      *
145      * @Then /^I should see a feedback field for "([^"]*)" and grade item "([^"]*)"$/
146      * @param string $student
147      * @param string $itemname
148      * @return Then
149      */
150     public function i_should_see_feedback_field($student, $itemname) {
151         $xpath = $this->get_student_and_grade_feedback_selector($student, $itemname);
153         return new Then('"' . $this->escape($xpath) . '" "xpath_element" should be visible');
154     }
156     /**
157      * Look for a lack of the grade editing field.
158      *
159      * @Then /^I should not see a grade field for "([^"]*)" and grade item "([^"]*)"$/
160      * @param string $student
161      * @param string $itemname
162      * @return Then
163      */
164     public function i_should_not_see_grade_field($student, $itemname) {
165         $xpath = $this->get_student_and_grade_value_selector($student, $itemname);
167         return new Then('"' . $this->escape($xpath) . '" "xpath_element" should not exist');
168     }
170     /**
171      * Look for a lack of the feedback editing field.
172      *
173      * @Then /^I should not see a feedback field for "([^"]*)" and grade item "([^"]*)"$/
174      * @param string $student
175      * @param string $itemname
176      * @return Then
177      */
178     public function i_should_not_see_feedback_field($student, $itemname) {
179         $xpath = $this->get_student_and_grade_feedback_selector($student, $itemname);
181         return new Then('"' . $this->escape($xpath) . '" "xpath_element" should not exist');
182     }
184     /**
185      * Gets the user id from its name.
186      *
187      * @throws Exception
188      * @param string $name
189      * @return int
190      */
191     protected function get_user_id($name) {
192         global $DB;
193         $names = explode(' ', $name);
195         if (!$id = $DB->get_field('user', 'id', array('firstname' => $names[0], 'lastname' => $names[1]))) {
196             throw new Exception('The specified user with username "' . $name . '" does not exist');
197         }
198         return $id;
199     }
201     /**
202      * Gets the grade item id from its name.
203      *
204      * @throws Exception
205      * @param string $itemname
206      * @return int
207      */
208     protected function get_grade_item_id($itemname) {
209         global $DB;
211         if ($id = $DB->get_field('grade_items', 'id', array('itemname' => $itemname))) {
212             return $id;
213         }
215         // The course total is a special case.
216         if ($itemname === "Course total") {
217             if (!$id = $DB->get_field('grade_items', 'id', array('itemtype' => 'course'))) {
218                 throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist');
219             }
220             return $id;
221         }
223         // Find a category with the name.
224         if ($catid = $DB->get_field('grade_categories', 'id', array('fullname' => $itemname))) {
225             if ($id = $DB->get_field('grade_items', 'id', array('iteminstance' => $catid))) {
226                 return $id;
227             }
228         }
230         throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist');
231     }
233     /**
234      * Gets unique xpath selector for a student/grade item combo.
235      *
236      * @throws Exception
237      * @param string $student
238      * @param string $itemname
239      * @return string
240      */
241     protected function get_student_and_grade_cell_selector($student, $itemname) {
242         $itemid = 'u' . $this->get_user_id($student) . 'i' . $this->get_grade_item_id($itemname);
243         return "//table[@id='user-grades']//td[@id='" . $itemid . "']";
244     }
246     /**
247      * Gets xpath for a particular student/grade item grade value cell.
248      *
249      * @throws Exception
250      * @param string $student
251      * @param string $itemname
252      * @return string
253      */
254     protected function get_student_and_grade_value_selector($student, $itemname) {
255         $cell = $this->get_student_and_grade_cell_selector($student, $itemname);
256         return $cell . "//*[contains(@id, 'grade_') or @name='ajaxgrade']";
257     }
259     /**
260      * Gets xpath for a particular student/grade item feedback cell.
261      *
262      * @throws Exception
263      * @param string $student
264      * @param string $itemname
265      * @return string
266      */
267     protected function get_student_and_grade_feedback_selector($student, $itemname) {
268         $cell = $this->get_student_and_grade_cell_selector($student, $itemname);
269         return $cell . "//input[contains(@id, 'feedback_') or @name='ajaxfeedback']";
270     }