Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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