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.
   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   * Class representing a named selector that can be used in Behat tests.
  19   *
  20   * @package    core
  21   * @category   test
  22   * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  /**
  27   * Class representing a named selector that can be used in Behat tests.
  28   *
  29   * Named selectors are what make Behat steps like
  30   *   Then I should see "Useful text" in the "General" "fieldset"
  31   * Here, "fieldset" is the named selector, and "General" is the locator.
  32   *
  33   * Selectors can either be exact, in which case the locator needs to
  34   * match exactly, or can be partial, for example the way
  35   *   When I click "Save" "button"
  36   * will trigger a "Save changes" button.
  37   *
  38   * Instances of this class get returned by the get_exact_named_selectors()
  39   * and get_partial_named_selectors() methods in classes like behat_mod_mymod.
  40   * The code that makes the magic work is in the trait behat_named_selector
  41   * used by both behat_exact_named_selector and behat_partial_named_selector.
  42   *
  43   * @package    core
  44   * @category   test
  45   * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
  46   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  47   */
  48  class behat_component_named_selector {
  49      /** @var string */
  50      protected $alias;
  51  
  52      /** @var array List of xpaths */
  53      protected $xpaths;
  54  
  55      /** @var string */
  56      protected $istextselector;
  57  
  58      /**
  59       * Create the selector definition.
  60       *
  61       * As an example, if you define
  62       *   new behat_component_named_selector('Message',
  63       *           [".//*[@data-conversation-id]//img[contains(@alt, %locator%)]/.."])
  64       * in get_partial_named_selectors in behat_message in
  65       * message/tests/behat/behat_message.php, then steps like
  66       *   When "Group 1" "core_message > Message" should exist
  67       * will work.
  68       *
  69       * Text selectors are things that contain other things (e.g. some particular text), e.g.
  70       *   Then I can see "Some text" in the "Whatever" "text_selector"
  71       * whereas non-text selectors are atomic things, like
  72       *   When I click the "Whatever" "widget".
  73       *
  74       * @param string $alias The 'friendly' name of the thing. This will be prefixed with the component name.
  75       *      For example, if the mod_mymod plugin, says 'Thingy', then "mod_mymod > Thingy" becomes a selector.
  76       * @param array $xpaths A list of xpaths one or more XPaths that the selector gets transformed into.
  77       * @param bool $istextselector Whether this selector can also be used as a text selector.
  78       */
  79      public function __construct(string $alias, array $xpaths, bool $istextselector = true) {
  80          $this->alias = $alias;
  81          $this->xpaths = $xpaths;
  82          $this->istextselector = $istextselector;
  83      }
  84  
  85      /**
  86       * Whether this is a text selector.
  87       *
  88       * @return bool
  89       */
  90      public function is_text_selector(): bool {
  91          return $this->istextselector;
  92      }
  93  
  94      /**
  95       * Get the name of the selector.
  96       * This is a back-end feature and contains a namespaced md5 of the human-readable name.
  97       *
  98       * @param string $component
  99       * @return string
 100       */
 101      public function get_name(string $component): string {
 102          return implode('_', [$component, md5($this->alias)]);
 103      }
 104  
 105      /**
 106       * Get the alias of the selector.
 107       * This is the human-readable name that you would typically interact with.
 108       *
 109       * @param string $component
 110       * @return string
 111       */
 112      public function get_alias(string $component): string {
 113          return implode(" > ", [$component, $this->alias]);;
 114      }
 115  
 116      /**
 117       * Get the list of combined xpaths.
 118       *
 119       * @return string The list of xpaths combined with the xpath | (OR) operator
 120       */
 121      public function get_combined_xpath(): string {
 122          return implode(' | ', $this->xpaths);
 123      }
 124  }