[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/tests/behat/ -> behat_forms.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   * Steps definitions related with forms.
  19   *
  20   * @package    core
  21   * @category   test
  22   * @copyright  2012 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  require_once (__DIR__ . '/../../../lib/behat/behat_base.php');
  29  require_once (__DIR__ . '/../../../lib/behat/behat_field_manager.php');
  30  
  31  use Behat\Gherkin\Node\TableNode as TableNode,
  32      Behat\Gherkin\Node\PyStringNode as PyStringNode,
  33      Behat\Mink\Exception\ExpectationException as ExpectationException,
  34      Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
  35  
  36  /**
  37   * Forms-related steps definitions.
  38   *
  39   * @package    core
  40   * @category   test
  41   * @copyright  2012 David Monllaó
  42   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  43   */
  44  class behat_forms extends behat_base {
  45  
  46      /**
  47       * Presses button with specified id|name|title|alt|value.
  48       *
  49       * @When /^I press "(?P<button_string>(?:[^"]|\\")*)"$/
  50       * @throws ElementNotFoundException Thrown by behat_base::find
  51       * @param string $button
  52       */
  53      public function press_button($button) {
  54  
  55          // Ensures the button is present.
  56          $buttonnode = $this->find_button($button);
  57          // Focus on button to ensure it is in viewport, before pressing it.
  58          if ($this->running_javascript()) {
  59              $buttonnode->focus();
  60          }
  61          $buttonnode->press();
  62      }
  63  
  64      /**
  65       * Press button with specified id|name|title|alt|value and switch to main window.
  66       *
  67       * @When /^I press "(?P<button_string>(?:[^"]|\\")*)" and switch to main window$/
  68       * @throws ElementNotFoundException Thrown by behat_base::find
  69       * @param string $button
  70       */
  71      public function press_button_and_switch_to_main_window($button) {
  72          // Ensures the button is present, before pressing.
  73          $buttonnode = $this->find_button($button);
  74          $buttonnode->press();
  75  
  76          // Switch to main window.
  77          $this->getSession()->switchToWindow(behat_general::MAIN_WINDOW_NAME);
  78      }
  79  
  80      /**
  81       * Fills a form with field/value data. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
  82       *
  83       * @Given /^I set the following fields to these values:$/
  84       * @throws ElementNotFoundException Thrown by behat_base::find
  85       * @param TableNode $data
  86       */
  87      public function i_set_the_following_fields_to_these_values(TableNode $data) {
  88  
  89          // Expand all fields in case we have.
  90          $this->expand_all_fields();
  91  
  92          $datahash = $data->getRowsHash();
  93  
  94          // The action depends on the field type.
  95          foreach ($datahash as $locator => $value) {
  96              $this->set_field_value($locator, $value);
  97          }
  98      }
  99  
 100      /**
 101       * Expands all moodleform's fields, including collapsed fieldsets and advanced fields if they are present.
 102       * @Given /^I expand all fieldsets$/
 103       */
 104      public function i_expand_all_fieldsets() {
 105          $this->expand_all_fields();
 106      }
 107  
 108      /**
 109       * Expands all moodle form fieldsets if they exists.
 110       *
 111       * Externalized from i_expand_all_fields to call it from
 112       * other form-related steps without having to use steps-group calls.
 113       *
 114       * @throws ElementNotFoundException Thrown by behat_base::find_all
 115       * @return void
 116       */
 117      protected function expand_all_fields() {
 118          // Expand only if JS mode, else not needed.
 119          if (!$this->running_javascript()) {
 120              return;
 121          }
 122  
 123          // We already know that we waited for the DOM and the JS to be loaded, even the editor
 124          // so, we will use the reduced timeout as it is a common task and we should save time.
 125          try {
 126  
 127              // Expand fieldsets link.
 128              $xpath = "//div[@class='collapsible-actions']" .
 129                  "/descendant::a[contains(concat(' ', @class, ' '), ' collapseexpand ')]" .
 130                  "[not(contains(concat(' ', @class, ' '), ' collapse-all '))]";
 131              $collapseexpandlink = $this->find('xpath', $xpath, false, false, self::REDUCED_TIMEOUT);
 132              $collapseexpandlink->click();
 133  
 134          } catch (ElementNotFoundException $e) {
 135              // The behat_base::find() method throws an exception if there are no elements,
 136              // we should not fail a test because of this. We continue if there are not expandable fields.
 137          }
 138  
 139          // Different try & catch as we can have expanded fieldsets with advanced fields on them.
 140          try {
 141  
 142              // Expand all fields xpath.
 143              $showmorexpath = "//a[normalize-space(.)='" . get_string('showmore', 'form') . "']" .
 144                  "[contains(concat(' ', normalize-space(@class), ' '), ' moreless-toggler')]";
 145  
 146              // We don't wait here as we already waited when getting the expand fieldsets links.
 147              if (!$showmores = $this->getSession()->getPage()->findAll('xpath', $showmorexpath)) {
 148                  return;
 149              }
 150  
 151              // Funny thing about this, with findAll() we specify a pattern and each element matching the pattern is added to the array
 152              // with of xpaths with a [0], [1]... sufix, but when we click on an element it does not matches the specified xpath
 153              // anymore (now is a "Show less..." link) so [1] becomes [0], that's why we always click on the first XPath match,
 154              // will be always the next one.
 155              $iterations = count($showmores);
 156              for ($i = 0; $i < $iterations; $i++) {
 157                  $showmores[0]->click();
 158              }
 159  
 160          } catch (ElementNotFoundException $e) {
 161              // We continue with the test.
 162          }
 163  
 164      }
 165  
 166      /**
 167       * Sets the field to wwwroot plus the given path. Include the first slash.
 168       *
 169       * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to local url "(?P<field_path_string>(?:[^"]|\\")*)"$/
 170       * @throws ElementNotFoundException Thrown by behat_base::find
 171       * @param string $field
 172       * @param string $path
 173       * @return void
 174       */
 175      public function i_set_the_field_to_local_url($field, $path) {
 176          global $CFG;
 177          $this->set_field_value($field, $CFG->wwwroot . $path);
 178      }
 179  
 180      /**
 181       * Sets the specified value to the field.
 182       *
 183       * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/
 184       * @throws ElementNotFoundException Thrown by behat_base::find
 185       * @param string $field
 186       * @param string $value
 187       * @return void
 188       */
 189      public function i_set_the_field_to($field, $value) {
 190          $this->set_field_value($field, $value);
 191      }
 192  
 193      /**
 194       * Press the key in the field to trigger the javascript keypress event
 195       *
 196       * Note that the character key will not actually be typed in the input field
 197       *
 198       * @Given /^I press key "(?P<key_string>(?:[^"]|\\")*)" in the field "(?P<field_string>(?:[^"]|\\")*)"$/
 199       * @throws ElementNotFoundException Thrown by behat_base::find
 200       * @param string $key either char-code or character itself,
 201       *          may optionally be prefixed with ctrl-, alt-, shift- or meta-
 202       * @param string $field
 203       * @return void
 204       */
 205      public function i_press_key_in_the_field($key, $field) {
 206          if (!$this->running_javascript()) {
 207              throw new DriverException('Key press step is not available with Javascript disabled');
 208          }
 209          $fld = behat_field_manager::get_form_field_from_label($field, $this);
 210          $modifier = null;
 211          $char = $key;
 212          if (preg_match('/-/', $key)) {
 213              list($modifier, $char) = preg_split('/-/', $key, 2);
 214          }
 215          if (is_numeric($char)) {
 216              $char = (int)$char;
 217          }
 218          $fld->key_press($char, $modifier);
 219      }
 220  
 221      /**
 222       * Sets the specified value to the field.
 223       *
 224       * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to multiline$/
 225       * @throws ElementNotFoundException Thrown by behat_base::find
 226       * @param string $field
 227       * @param PyStringNode $value
 228       * @return void
 229       */
 230      public function i_set_the_field_to_multiline($field, PyStringNode $value) {
 231          $this->set_field_value($field, (string)$value);
 232      }
 233  
 234      /**
 235       * Sets the specified value to the field with xpath.
 236       *
 237       * @Given /^I set the field with xpath "(?P<fieldxpath_string>(?:[^"]|\\")*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/
 238       * @throws ElementNotFoundException Thrown by behat_base::find
 239       * @param string $field
 240       * @param string $value
 241       * @return void
 242       */
 243      public function i_set_the_field_with_xpath_to($fieldxpath, $value) {
 244          $fieldNode = $this->find('xpath', $fieldxpath);
 245          $field = behat_field_manager::get_form_field($fieldNode, $this->getSession());
 246          $field->set_value($value);
 247      }
 248  
 249      /**
 250       * Checks, the field matches the value. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
 251       *
 252       * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/
 253       * @throws ElementNotFoundException Thrown by behat_base::find
 254       * @param string $field
 255       * @param string $value
 256       * @return void
 257       */
 258      public function the_field_matches_value($field, $value) {
 259  
 260          // Get the field.
 261          $formfield = behat_field_manager::get_form_field_from_label($field, $this);
 262  
 263          // Checks if the provided value matches the current field value.
 264          if (!$formfield->matches($value)) {
 265              $fieldvalue = $formfield->get_value();
 266              throw new ExpectationException(
 267                  'The \'' . $field . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' ,
 268                  $this->getSession()
 269              );
 270          }
 271      }
 272  
 273      /**
 274       * Checks, the field does not match the value. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
 275       *
 276       * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" does not match value "(?P<field_value_string>(?:[^"]|\\")*)"$/
 277       * @throws ExpectationException
 278       * @throws ElementNotFoundException Thrown by behat_base::find
 279       * @param string $field
 280       * @param string $value
 281       * @return void
 282       */
 283      public function the_field_does_not_match_value($field, $value) {
 284  
 285          // Get the field.
 286          $formfield = behat_field_manager::get_form_field_from_label($field, $this);
 287  
 288          // Checks if the provided value matches the current field value.
 289          if ($formfield->matches($value)) {
 290              throw new ExpectationException(
 291                  'The \'' . $field . '\' value matches \'' . $value . '\' and it should not match it' ,
 292                  $this->getSession()
 293              );
 294          }
 295      }
 296  
 297      /**
 298       * Checks, the field matches the value.
 299       *
 300       * @Then /^the field with xpath "(?P<xpath_string>(?:[^"]|\\")*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/
 301       * @throws ExpectationException
 302       * @throws ElementNotFoundException Thrown by behat_base::find
 303       * @param string $fieldxpath
 304       * @param string $value
 305       * @return void
 306       */
 307      public function the_field_with_xpath_matches_value($fieldxpath, $value) {
 308  
 309          // Get the field.
 310          $fieldnode = $this->find('xpath', $fieldxpath);
 311          $formfield = behat_field_manager::get_form_field($fieldnode, $this->getSession());
 312  
 313          // Checks if the provided value matches the current field value.
 314          if (!$formfield->matches($value)) {
 315              $fieldvalue = $formfield->get_value();
 316              throw new ExpectationException(
 317                  'The \'' . $fieldxpath . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' ,
 318                  $this->getSession()
 319              );
 320          }
 321      }
 322  
 323      /**
 324       * Checks, the field does not match the value.
 325       *
 326       * @Then /^the field with xpath "(?P<xpath_string>(?:[^"]|\\")*)" does not match value "(?P<field_value_string>(?:[^"]|\\")*)"$/
 327       * @throws ExpectationException
 328       * @throws ElementNotFoundException Thrown by behat_base::find
 329       * @param string $fieldxpath
 330       * @param string $value
 331       * @return void
 332       */
 333      public function the_field_with_xpath_does_not_match_value($fieldxpath, $value) {
 334  
 335          // Get the field.
 336          $fieldnode = $this->find('xpath', $fieldxpath);
 337          $formfield = behat_field_manager::get_form_field($fieldnode, $this->getSession());
 338  
 339          // Checks if the provided value matches the current field value.
 340          if ($formfield->matches($value)) {
 341              throw new ExpectationException(
 342                  'The \'' . $fieldxpath . '\' value matches \'' . $value . '\' and it should not match it' ,
 343                  $this->getSession()
 344              );
 345          }
 346      }
 347  
 348      /**
 349       * Checks, the provided field/value matches. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
 350       *
 351       * @Then /^the following fields match these values:$/
 352       * @throws ExpectationException
 353       * @param TableNode $data Pairs of | field | value |
 354       */
 355      public function the_following_fields_match_these_values(TableNode $data) {
 356  
 357          // Expand all fields in case we have.
 358          $this->expand_all_fields();
 359  
 360          $datahash = $data->getRowsHash();
 361  
 362          // The action depends on the field type.
 363          foreach ($datahash as $locator => $value) {
 364              $this->the_field_matches_value($locator, $value);
 365          }
 366      }
 367  
 368      /**
 369       * Checks that the provided field/value pairs don't match. More info in http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps.
 370       *
 371       * @Then /^the following fields do not match these values:$/
 372       * @throws ExpectationException
 373       * @param TableNode $data Pairs of | field | value |
 374       */
 375      public function the_following_fields_do_not_match_these_values(TableNode $data) {
 376  
 377          // Expand all fields in case we have.
 378          $this->expand_all_fields();
 379  
 380          $datahash = $data->getRowsHash();
 381  
 382          // The action depends on the field type.
 383          foreach ($datahash as $locator => $value) {
 384              $this->the_field_does_not_match_value($locator, $value);
 385          }
 386      }
 387  
 388      /**
 389       * Checks, that given select box contains the specified option.
 390       *
 391       * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should contain "(?P<option_string>(?:[^"]|\\")*)"$/
 392       * @throws ExpectationException
 393       * @throws ElementNotFoundException Thrown by behat_base::find
 394       * @param string $select The select element name
 395       * @param string $option The option text/value. Plain value or comma separated
 396       *                       values if multiple. Commas in multiple values escaped with backslash.
 397       */
 398      public function the_select_box_should_contain($select, $option) {
 399  
 400          $selectnode = $this->find_field($select);
 401          $multiple = $selectnode->hasAttribute('multiple');
 402          $optionsarr = array(); // Array of passed value/text options to test.
 403  
 404          if ($multiple) {
 405              // Can pass multiple comma separated, with valuable commas escaped with backslash.
 406              foreach (preg_replace('/\\\,/', ',',  preg_split('/(?<!\\\),/', $option)) as $opt) {
 407                  $optionsarr[] = trim($opt);
 408              }
 409          } else {
 410              // Only one option has been passed.
 411              $optionsarr[] = trim($option);
 412          }
 413  
 414          // Now get all the values and texts in the select.
 415          $options = $selectnode->findAll('xpath', '//option');
 416          $values = array();
 417          foreach ($options as $opt) {
 418              $values[trim($opt->getValue())] = trim($opt->getText());
 419          }
 420  
 421          foreach ($optionsarr as $opt) {
 422              // Verify every option is a valid text or value.
 423              if (!in_array($opt, $values) && !array_key_exists($opt, $values)) {
 424                  throw new ExpectationException(
 425                      'The select box "' . $select . '" does not contain the option "' . $opt . '"',
 426                      $this->getSession()
 427                  );
 428              }
 429          }
 430      }
 431  
 432      /**
 433       * Checks, that given select box does not contain the specified option.
 434       *
 435       * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should not contain "(?P<option_string>(?:[^"]|\\")*)"$/
 436       * @throws ExpectationException
 437       * @throws ElementNotFoundException Thrown by behat_base::find
 438       * @param string $select The select element name
 439       * @param string $option The option text/value. Plain value or comma separated
 440       *                       values if multiple. Commas in multiple values escaped with backslash.
 441       */
 442      public function the_select_box_should_not_contain($select, $option) {
 443  
 444          $selectnode = $this->find_field($select);
 445          $multiple = $selectnode->hasAttribute('multiple');
 446          $optionsarr = array(); // Array of passed value/text options to test.
 447  
 448          if ($multiple) {
 449              // Can pass multiple comma separated, with valuable commas escaped with backslash.
 450              foreach (preg_replace('/\\\,/', ',',  preg_split('/(?<!\\\),/', $option)) as $opt) {
 451                  $optionsarr[] = trim($opt);
 452              }
 453          } else {
 454              // Only one option has been passed.
 455              $optionsarr[] = trim($option);
 456          }
 457  
 458          // Now get all the values and texts in the select.
 459          $options = $selectnode->findAll('xpath', '//option');
 460          $values = array();
 461          foreach ($options as $opt) {
 462              $values[trim($opt->getValue())] = trim($opt->getText());
 463          }
 464  
 465          foreach ($optionsarr as $opt) {
 466              // Verify every option is not a valid text or value.
 467              if (in_array($opt, $values) || array_key_exists($opt, $values)) {
 468                  throw new ExpectationException(
 469                      'The select box "' . $select . '" contains the option "' . $opt . '"',
 470                      $this->getSession()
 471                  );
 472              }
 473          }
 474      }
 475  
 476      /**
 477       * Generic field setter.
 478       *
 479       * Internal API method, a generic *I set "VALUE" to "FIELD" field*
 480       * could be created based on it.
 481       *
 482       * @param string $fieldlocator The pointer to the field, it will depend on the field type.
 483       * @param string $value
 484       * @return void
 485       */
 486      protected function set_field_value($fieldlocator, $value) {
 487  
 488          // We delegate to behat_form_field class, it will
 489          // guess the type properly as it is a select tag.
 490          $field = behat_field_manager::get_form_field_from_label($fieldlocator, $this);
 491          $field->set_value($value);
 492      }
 493  
 494      /**
 495       * Select a value from single select and redirect.
 496       *
 497       * @Given /^I select "(?P<singleselect_option_string>(?:[^"]|\\")*)" from the "(?P<singleselect_name_string>(?:[^"]|\\")*)" singleselect$/
 498       */
 499      public function i_select_from_the_singleselect($option, $singleselect) {
 500  
 501          $this->execute('behat_forms::i_set_the_field_to', array($this->escape($singleselect), $this->escape($option)));
 502  
 503          if (!$this->running_javascript()) {
 504              // Press button in the specified select container.
 505              $containerxpath = "//div[" .
 506                  "(contains(concat(' ', normalize-space(@class), ' '), ' singleselect ') " .
 507                      "or contains(concat(' ', normalize-space(@class), ' '), ' urlselect ')".
 508                  ") and (
 509                  .//label[contains(normalize-space(string(.)), '" . $singleselect . "')] " .
 510                      "or .//select[(./@name='" . $singleselect . "' or ./@id='". $singleselect . "')]" .
 511                  ")]";
 512  
 513              $this->execute('behat_general::i_click_on_in_the',
 514                  array(get_string('go'), "button", $containerxpath, "xpath_element")
 515              );
 516          }
 517      }
 518  
 519  }


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