Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 39 and 311]

   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 markers.
  19   *
  20   * @package   qtype_ddmarker
  21   * @category  test
  22   * @copyright 2015 The Open 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  /**
  31   * Steps definitions related with the drag and drop markers question type.
  32   *
  33   * @copyright 2015 The Open University
  34   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class behat_qtype_ddmarker extends behat_base {
  37  
  38      /**
  39       * Get the xpath for a given drag item.
  40       *
  41       * @param string $marker the text of the item to drag.
  42       * @param bool $iskeyboard is using keyboard or not.
  43       * @return string the xpath expression.
  44       */
  45      protected function marker_xpath($marker, $iskeyboard = false) {
  46          if ($iskeyboard) {
  47              return '//span[contains(@class, "marker") and not(contains(@class, "dragplaceholder")) ' .
  48                      'and span[@class = "markertext" and contains(normalize-space(.), "' .
  49                      $this->escape($marker) . '")]]';
  50          }
  51          return '//span[contains(@class, "marker") and contains(@class, "unneeded") ' .
  52                  'and not(contains(@class, "dragplaceholder")) and span[@class = "markertext" and contains(normalize-space(.), "' .
  53                  $this->escape($marker) . '")]]';
  54      }
  55  
  56      /**
  57       * Drag the drag item with the given text to the given space.
  58       *
  59       * @param string $marker the marker to drag. The label, optionally followed by ,<instance number> (int) if relevant.
  60       * @param string $coordinates the position to drag the marker to, 'x,y'.
  61       *
  62       * @Given /^I drag "(?P<marker>[^"]*)" to "(?P<coordinates>\d+,\d+)" in the drag and drop markers question$/
  63       */
  64      public function i_drag_to_in_the_drag_and_drop_markers_question($marker, $coordinates) {
  65          list($x, $y) = explode(',', $coordinates);
  66  
  67          // This is a bit nasty, but Behat (indeed Selenium) will only drag on
  68          // DOM node so that its centre is over the centre of anothe DOM node.
  69          // Therefore to make it drag to the specified place, we have to add
  70          // a target div.
  71          $markerxpath = $this->marker_xpath($marker);
  72          $this->execute_script("
  73                  (function() {
  74                      if (document.getElementById('target-{$x}-{$y}')) {
  75                          return;
  76                      }
  77                      var image = document.querySelector('.dropbackground');
  78                      var target = document.createElement('div');
  79                      target.setAttribute('id', 'target-{$x}-{$y}');
  80                      var container = document.querySelector('.droparea');
  81                      container.insertBefore(target, image);
  82                      var widthRatio = image.offsetWidth / image.naturalWidth;
  83                      var heightRatio = image.offsetHeight / image.naturalHeight;
  84                      var marker = document.evaluate('{$markerxpath}', document, null, XPathResult.ANY_TYPE, null).iterateNext();
  85                      var xadjusted = {$x} * widthRatio
  86                                      + (container.offsetWidth - image.offsetWidth) / 2
  87                                      + marker.offsetWidth / 2;
  88                      var yadjusted = {$y} * heightRatio
  89                                      + (container.offsetHeight - image.offsetHeight) / 2
  90                                      + marker.offsetHeight / 2;
  91                      target.style.setProperty('position', 'absolute');
  92                      target.style.setProperty('left', xadjusted + 'px');
  93                      target.style.setProperty('top', yadjusted + 'px');
  94                      target.style.setProperty('width', '1px');
  95                      target.style.setProperty('height', '1px');
  96                  }())"
  97          );
  98  
  99          $generalcontext = behat_context_helper::get('behat_general');
 100          $generalcontext->i_drag_and_i_drop_it_in($markerxpath,
 101                  'xpath_element', "#target-{$x}-{$y}", 'css_element');
 102      }
 103  
 104      /**
 105       * Type some characters while focussed on a given drop box.
 106       *
 107       * @param string $direction the direction key to press.
 108       * @param int $
 109       * @param string $marker the marker to drag. The label, optionally followed by ,<instance number> (int) if relevant.
 110       *
 111       * @Given /^I type "(?P<direction>up|down|left|right)" "(?P<repeats>\d+)" times on marker "(?P<marker>[^"]*)" in the drag and drop markers question$/
 112       */
 113      public function i_type_on_marker_in_the_drag_and_drop_markers_question($direction, $repeats, $marker) {
 114          $node = $this->get_selected_node('xpath_element', $this->marker_xpath($marker, true));
 115          $this->ensure_node_is_visible($node);
 116          $node->focus();
 117          for ($i = 0; $i < $repeats; $i++) {
 118              $this->execute('behat_general::i_press_named_key', ['', $direction]);
 119          }
 120      }
 121  }