[ Index ]

PHP Cross Reference of Unnamed Project

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              // This might go out of scope, finding element beyond the dom and fail. So fallback to guessing type.
  90              try {
  91                  $type = self::get_field_node_type($fieldnode, $session);
  92              } catch (WebDriver\Exception\InvalidSelector $e) {
  93                  $type = 'field';
  94              }
  95          }
  96  
  97          // If is not a moodleforms field use the base field type.
  98          if (empty($type)) {
  99              $type = 'field';
 100          }
 101  
 102          return self::get_field_instance($type, $fieldnode, $session);
 103      }
 104  
 105      /**
 106       * Returns the appropiate behat_form_field according to the provided type.
 107       *
 108       * It defaults to behat_form_field.
 109       *
 110       * @param string $type The field type (checkbox, date_selector, text...)
 111       * @param NodeElement $fieldnode
 112       * @param Session $session The behat session
 113       * @return behat_form_field
 114       */
 115      public static function get_field_instance($type, NodeElement $fieldnode, Session $session) {
 116  
 117          global $CFG;
 118  
 119          // If the field is not part of a moodleform, we should still try to find out
 120          // which field type are we dealing with.
 121          if ($type == 'field' &&
 122                  $guessedtype = self::guess_field_type($fieldnode, $session)) {
 123              $type = $guessedtype;
 124          }
 125  
 126          $classname = 'behat_form_' . $type;
 127  
 128          // Fallsback on the type guesser if nothing specific exists.
 129          $classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php';
 130          if (!file_exists($classpath)) {
 131              $classname = 'behat_form_field';
 132              $classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php';
 133          }
 134  
 135          // Returns the instance.
 136          require_once($classpath);
 137          return new $classname($session, $fieldnode);
 138      }
 139  
 140      /**
 141       * Guesses a basic field type and returns it.
 142       *
 143       * This method is intended to detect HTML form fields when no
 144       * moodleform-specific elements have been detected.
 145       *
 146       * @param NodeElement $fieldnode
 147       * @param Session $session
 148       * @return string|bool The field type or false.
 149       */
 150      public static function guess_field_type(NodeElement $fieldnode, Session $session) {
 151  
 152          // Textareas are considered text based elements.
 153          $tagname = strtolower($fieldnode->getTagName());
 154          if ($tagname == 'textarea') {
 155  
 156              // If there is an iframe with $id + _ifr there a TinyMCE editor loaded.
 157              $xpath = '//div[@id="' . $fieldnode->getAttribute('id') . 'editable"]';
 158              if ($session->getPage()->find('xpath', $xpath)) {
 159                  return 'editor';
 160              }
 161              return 'textarea';
 162  
 163          } else if ($tagname == 'input') {
 164              $type = $fieldnode->getAttribute('type');
 165              switch ($type) {
 166                  case 'text':
 167                  case 'password':
 168                  case 'email':
 169                  case 'file':
 170                      return 'text';
 171                  case 'checkbox':
 172                      return 'checkbox';
 173                      break;
 174                  case 'radio':
 175                      return 'radio';
 176                      break;
 177                  default:
 178                      // Here we return false because all text-based
 179                      // fields should be included in the first switch case.
 180                      return false;
 181              }
 182  
 183          } else if ($tagname == 'select') {
 184              // Select tag.
 185              return 'select';
 186          }
 187  
 188          // We can not provide a closer field type.
 189          return false;
 190      }
 191  
 192      /**
 193       * Detects when the field is a moodleform field type.
 194       *
 195       * Note that there are fields inside moodleforms that are not
 196       * moodleform element; this method can not detect this, this will
 197       * be managed by get_field_node_type, after failing to find the form
 198       * element element type.
 199       *
 200       * @param NodeElement $fieldnode
 201       * @return bool
 202       */
 203      protected static function is_moodleform_field(NodeElement $fieldnode) {
 204  
 205          // We already waited when getting the NodeElement and we don't want an exception if it's not part of a moodleform.
 206          $parentformfound = $fieldnode->find('xpath',
 207              "/ancestor::fieldset" .
 208              "/ancestor::form[contains(concat(' ', normalize-space(@class), ' '), ' mform ')]"
 209          );
 210  
 211          return ($parentformfound != false);
 212      }
 213  
 214      /**
 215       * Recursive method to find the field type.
 216       *
 217       * Depending on the field the felement class node is in a level or in another. We
 218       * look recursively for a parent node with a 'felement' class to find the field type.
 219       *
 220       * @param NodeElement $fieldnode The current node.
 221       * @param Session $session The behat browser session
 222       * @return mixed A NodeElement if we continue looking for the element type and String or false when we are done.
 223       */
 224      protected static function get_field_node_type(NodeElement $fieldnode, Session $session) {
 225  
 226          // Special handling for availability field which requires custom JavaScript.
 227          if ($fieldnode->getAttribute('name') === 'availabilityconditionsjson') {
 228              return 'availability';
 229          }
 230  
 231          // We look for a parent node with 'felement' class.
 232          if ($class = $fieldnode->getParent()->getAttribute('class')) {
 233  
 234              if (strstr($class, 'felement') != false) {
 235                  // Remove 'felement f' from class value.
 236                  return substr($class, 10);
 237              }
 238  
 239              // Stop propagation through the DOM, if it does not have a felement is not part of a moodle form.
 240              if (strstr($class, 'fcontainer') != false) {
 241                  return false;
 242              }
 243          }
 244  
 245          return self::get_field_node_type($fieldnode->getParent(), $session);
 246      }
 247  
 248      /**
 249       * Gets an instance of the form field.
 250       *
 251       * Not all the fields are part of a moodle form, in this
 252       * cases it fallsback to the generic form field. Also note
 253       * that this generic field type is using a generic setValue()
 254       * method from the Behat API, which is not always good to set
 255       * the value of form elements.
 256       *
 257       * @deprecated since Moodle 2.6 MDL-39634 - please do not use this function any more.
 258       * @todo MDL-XXXXX This will be deleted in Moodle 2.8
 259       * @see behat_field_manager::get_form_field()
 260       * @param NodeElement $fieldnode
 261       * @param string $locator
 262       * @param Session $session The behat browser session
 263       * @return behat_form_field
 264       */
 265      public static function get_field(NodeElement $fieldnode, $locator, Session $session) {
 266          debugging('Function behat_field_manager::get_field() is deprecated, ' .
 267              'please use function behat_field_manager::get_form_field() instead', DEBUG_DEVELOPER);
 268  
 269          return self::get_form_field($fieldnode, $session);
 270      }
 271  
 272      /**
 273       * Recursive method to find the field type.
 274       *
 275       * Depending on the field the felement class node is in a level or in another. We
 276       * look recursively for a parent node with a 'felement' class to find the field type.
 277       *
 278       * @deprecated since Moodle 2.6 MDL-39634 - please do not use this function any more.
 279       * @todo MDL-XXXXX This will be deleted in Moodle 2.8
 280       * @see behat_field_manager::get_field_node_type()
 281       * @param NodeElement $fieldnode The current node.
 282       * @param string $locator
 283       * @param Session $session The behat browser session
 284       * @return mixed A NodeElement if we continue looking for the element type and String or false when we are done.
 285       */
 286      protected static function get_node_type(NodeElement $fieldnode, $locator, Session $session) {
 287          debugging('Function behat_field_manager::get_node_type() is deprecated, ' .
 288              'please use function behat_field_manager::get_field_node_type() instead', DEBUG_DEVELOPER);
 289  
 290          return self::get_field_node_type($fieldnode, $session);
 291      }
 292  
 293  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1