[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/behat/ -> behat_field_manager.php (source)

   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   * Form fields helper.
  19   *
  20   * @package    core
  21   * @category   test
  22   * @copyright  2013 David Monllaó
  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  use Behat\Mink\Session as Session,
  29      Behat\Mink\Element\NodeElement as NodeElement,
  30      Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException,
  31      Behat\MinkExtension\Context\RawMinkContext as RawMinkContext;
  32  
  33  /**
  34   * Helper to interact with form fields.
  35   *
  36   * @package    core
  37   * @category   test
  38   * @copyright  2013 David Monllaó
  39   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  40   */
  41  class behat_field_manager {
  42  
  43      /**
  44       * Gets an instance of the form field from it's label
  45       *
  46       * @param string $label
  47       * @param RawMinkContext $context
  48       * @return behat_form_field
  49       */
  50      public static function get_form_field_from_label($label, RawMinkContext $context) {
  51  
  52          // There are moodle form elements that are not directly related with
  53          // a basic HTML form field, we should also take care of them.
  54          try {
  55              // The DOM node.
  56              $fieldnode = $context->find_field($label);
  57          } catch (ElementNotFoundException $fieldexception) {
  58  
  59              // Looking for labels that points to filemanagers.
  60              try {
  61                  $fieldnode = $context->find_filemanager($label);
  62              } catch (ElementNotFoundException $filemanagerexception) {
  63                  // We want the generic 'field' exception.
  64                  throw $fieldexception;
  65              }
  66          }
  67  
  68          // The behat field manager.
  69          return self::get_form_field($fieldnode, $context->getSession());
  70      }
  71  
  72      /**
  73       * Gets an instance of the form field.
  74       *
  75       * Not all the fields are part of a moodle form, in this
  76       * cases it fallsback to the generic form field. Also note
  77       * that this generic field type is using a generic setValue()
  78       * method from the Behat API, which is not always good to set
  79       * the value of form elements.
  80       *
  81       * @param NodeElement $fieldnode
  82       * @param Session $session The behat browser session
  83       * @return behat_form_field
  84       */
  85      public static function get_form_field(NodeElement $fieldnode, Session $session) {
  86  
  87          // Get the field type if is part of a moodleform.
  88          if (self::is_moodleform_field($fieldnode)) {
  89              $type = self::get_field_node_type($fieldnode, $session);
  90          }
  91  
  92          // If is not a moodleforms field use the base field type.
  93          if (empty($type)) {
  94              $type = 'field';
  95          }
  96  
  97          return self::get_field_instance($type, $fieldnode, $session);
  98      }
  99  
 100      /**
 101       * Returns the appropiate behat_form_field according to the provided type.
 102       *
 103       * It defaults to behat_form_field.
 104       *
 105       * @param string $type The field type (checkbox, date_selector, text...)
 106       * @param NodeElement $fieldnode
 107       * @param Session $session The behat session
 108       * @return behat_form_field
 109       */
 110      public static function get_field_instance($type, NodeElement $fieldnode, Session $session) {
 111  
 112          global $CFG;
 113  
 114          // If the field is not part of a moodleform, we should still try to find out
 115          // which field type are we dealing with.
 116          if ($type == 'field' &&
 117                  $guessedtype = self::guess_field_type($fieldnode, $session)) {
 118              $type = $guessedtype;
 119          }
 120  
 121          $classname = 'behat_form_' . $type;
 122  
 123          // Fallsback on the type guesser if nothing specific exists.
 124          $classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php';
 125          if (!file_exists($classpath)) {
 126              $classname = 'behat_form_field';
 127              $classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php';
 128          }
 129  
 130          // Returns the instance.
 131          require_once($classpath);
 132          return new $classname($session, $fieldnode);
 133      }
 134  
 135      /**
 136       * Guesses a basic field type and returns it.
 137       *
 138       * This method is intended to detect HTML form fields when no
 139       * moodleform-specific elements have been detected.
 140       *
 141       * @param NodeElement $fieldnode
 142       * @param Session $session
 143       * @return string|bool The field type or false.
 144       */
 145      public static function guess_field_type(NodeElement $fieldnode, Session $session) {
 146  
 147          // Textareas are considered text based elements.
 148          $tagname = strtolower($fieldnode->getTagName());
 149          if ($tagname == 'textarea') {
 150  
 151              // If there is an iframe with $id + _ifr there a TinyMCE editor loaded.
 152              $xpath = '//div[@id="' . $fieldnode->getAttribute('id') . 'editable"]';
 153              if ($session->getPage()->find('xpath', $xpath)) {
 154                  return 'editor';
 155              }
 156              return 'textarea';
 157  
 158          } else if ($tagname == 'input') {
 159              $type = $fieldnode->getAttribute('type');
 160              switch ($type) {
 161                  case 'text':
 162                  case 'password':
 163                  case 'email':
 164                  case 'file':
 165                      return 'text';
 166                  case 'checkbox':
 167                      return 'checkbox';
 168                      break;
 169                  case 'radio':
 170                      return 'radio';
 171                      break;
 172                  default:
 173                      // Here we return false because all text-based
 174                      // fields should be included in the first switch case.
 175                      return false;
 176              }
 177  
 178          } else if ($tagname == 'select') {
 179              // Select tag.
 180              return 'select';
 181          }
 182  
 183          // We can not provide a closer field type.
 184          return false;
 185      }
 186  
 187      /**
 188       * Detects when the field is a moodleform field type.
 189       *
 190       * Note that there are fields inside moodleforms that are not
 191       * moodleform element; this method can not detect this, this will
 192       * be managed by get_field_node_type, after failing to find the form
 193       * element element type.
 194       *
 195       * @param NodeElement $fieldnode
 196       * @return bool
 197       */
 198      protected static function is_moodleform_field(NodeElement $fieldnode) {
 199  
 200          // We already waited when getting the NodeElement and we don't want an exception if it's not part of a moodleform.
 201          $parentformfound = $fieldnode->find('xpath',
 202              "/ancestor::fieldset" .
 203              "/ancestor::form[contains(concat(' ', normalize-space(@class), ' '), ' mform ')]"
 204          );
 205  
 206          return ($parentformfound != false);
 207      }
 208  
 209      /**
 210       * Recursive method to find the field type.
 211       *
 212       * Depending on the field the felement class node is in a level or in another. We
 213       * look recursively for a parent node with a 'felement' class to find the field type.
 214       *
 215       * @param NodeElement $fieldnode The current node.
 216       * @param Session $session The behat browser session
 217       * @return mixed A NodeElement if we continue looking for the element type and String or false when we are done.
 218       */
 219      protected static function get_field_node_type(NodeElement $fieldnode, Session $session) {
 220  
 221          // Special handling for availability field which requires custom JavaScript.
 222          if ($fieldnode->getAttribute('name') === 'availabilityconditionsjson') {
 223              return 'availability';
 224          }
 225  
 226          // We look for a parent node with 'felement' class.
 227          if ($class = $fieldnode->getParent()->getAttribute('class')) {
 228  
 229              if (strstr($class, 'felement') != false) {
 230                  // Remove 'felement f' from class value.
 231                  return substr($class, 10);
 232              }
 233  
 234              // Stop propagation through the DOM, if it does not have a felement is not part of a moodle form.
 235              if (strstr($class, 'fcontainer') != false) {
 236                  return false;
 237              }
 238          }
 239  
 240          return self::get_field_node_type($fieldnode->getParent(), $session);
 241      }
 242  
 243      /**
 244       * Gets an instance of the form field.
 245       *
 246       * Not all the fields are part of a moodle form, in this
 247       * cases it fallsback to the generic form field. Also note
 248       * that this generic field type is using a generic setValue()
 249       * method from the Behat API, which is not always good to set
 250       * the value of form elements.
 251       *
 252       * @deprecated since Moodle 2.6 MDL-39634 - please do not use this function any more.
 253       * @todo MDL-XXXXX This will be deleted in Moodle 2.8
 254       * @see behat_field_manager::get_form_field()
 255       * @param NodeElement $fieldnode
 256       * @param string $locator
 257       * @param Session $session The behat browser session
 258       * @return behat_form_field
 259       */
 260      public static function get_field(NodeElement $fieldnode, $locator, Session $session) {
 261          debugging('Function behat_field_manager::get_field() is deprecated, ' .
 262              'please use function behat_field_manager::get_form_field() instead', DEBUG_DEVELOPER);
 263  
 264          return self::get_form_field($fieldnode, $session);
 265      }
 266  
 267      /**
 268       * Recursive method to find the field type.
 269       *
 270       * Depending on the field the felement class node is in a level or in another. We
 271       * look recursively for a parent node with a 'felement' class to find the field type.
 272       *
 273       * @deprecated since Moodle 2.6 MDL-39634 - please do not use this function any more.
 274       * @todo MDL-XXXXX This will be deleted in Moodle 2.8
 275       * @see behat_field_manager::get_field_node_type()
 276       * @param NodeElement $fieldnode The current node.
 277       * @param string $locator
 278       * @param Session $session The behat browser session
 279       * @return mixed A NodeElement if we continue looking for the element type and String or false when we are done.
 280       */
 281      protected static function get_node_type(NodeElement $fieldnode, $locator, Session $session) {
 282          debugging('Function behat_field_manager::get_node_type() is deprecated, ' .
 283              'please use function behat_field_manager::get_field_node_type() instead', DEBUG_DEVELOPER);
 284  
 285          return self::get_field_node_type($fieldnode, $session);
 286      }
 287  
 288  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1