MDL-66559 behat: Documentation for component selectors
authorTim Hunt <T.J.Hunt@open.ac.uk>
Sat, 5 Oct 2019 12:50:43 +0000 (13:50 +0100)
committerAndrew Nicols <andrew@nicols.co.uk>
Fri, 11 Oct 2019 04:58:16 +0000 (12:58 +0800)
lib/behat/behat_base.php
lib/behat/classes/behat_context_helper.php
lib/behat/classes/component_named_replacement.php
lib/behat/classes/component_named_selector.php
lib/behat/classes/named_selector.php

index 5510ae6..4ebc6f6 100644 (file)
@@ -1111,6 +1111,21 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
     /**
      * Return a list of the exact named selectors for the component.
      *
+     * Named selectors are what make Behat steps like
+     *   Then I should see "Useful text" in the "General" "fieldset"
+     * work. Here, "fieldset" is the named selector, and "General" is the locator.
+     *
+     * If you override this method in your plugin (e.g. mod_mymod), to define
+     * new selectors specific to your plugin. For example, if you returned
+     *   new behat_component_named_selector('Thingy',
+     *           [".//some/xpath//img[contains(@alt, %locator%)]/.."])
+     * then
+     *   Then I should see "Useful text" in the "Whatever" "mod_mymod > Thingy"
+     * would work.
+     *
+     * This method should return a list of {@link behat_component_named_selector} and
+     * the docs on that class explain how it works.
+     *
      * @return behat_component_named_selector[]
      */
     public static function get_exact_named_selectors(): array {
@@ -1120,6 +1135,12 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
     /**
      * Return a list of the partial named selectors for the component.
      *
+     * Like the exact named selectors above, but the locator only
+     * needs to match part of the text. For example, the standard
+     * "button" is a partial selector, so:
+     *   When I click "Save" "button"
+     * will activate "Save changes".
+     *
      * @return behat_component_named_selector[]
      */
     public static function get_partial_named_selectors(): array {
@@ -1127,7 +1148,13 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
     }
 
     /**
-     * Return a list of the named replacements for the component.
+     * Return a list of the Mink named replacements for the component.
+     *
+     * Named replacements allow you to define parts of an xpath that can be reused multiple times, or in multiple
+     * xpaths.
+     *
+     * This method should return a list of {@link behat_component_named_replacement} and the docs on that class explain
+     * how it works.
      *
      * @return behat_component_named_replacement[]
      */
index 0a70011..d7a2b60 100644 (file)
@@ -118,7 +118,7 @@ class behat_context_helper {
     }
 
     /**
-     * Return whether there is a context of the specified classnme.
+     * Return whether there is a context of the specified classname.
      *
      * @param string $classname
      * @return bool
index a771c32..f11a4ce 100644 (file)
@@ -15,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Moodle-specific Mink replacements.
+ * A class for recording the definition of Mink replacements.
  *
  * @package    core
  * @category   test
  */
 
 /**
- * Moodle-specific Mink replacements.
+ * A class for recording the definition of Mink replacements for use in Mink selectors.
+ *
+ * These are comprised of a source string, and a replacement.
+ *
+ * During use the source string is converted from the string to be in the format:
+ *
+ *      %[component]/[string]%
+ *
+ * For example:
+ *
+ *      %mod_forum/title%
+ *
+ * Mink replacements are used in xpath translation to translate regularly used items such as title.
+ * Here is an example from the upstream Mink project:
+ *
+ * '%tagTextMatch%' => 'contains(normalize-space(string(.)), %locator%)'
+ *
+ * And can be used in an xpath:
+ *
+ *      .//label[%tagTextMatch%]
+ *
+ * This would be expanded to:
+ *
+ *      .//label[contains(normalize-space(string(.)), %locator%)]
+ *
+ * Replacements can also be used in other replacements, as long as that replacement is defined later.
+ *
+ *      '%linkMatch%' => '(%idMatch% or %tagTextMatch% or %titleMatch% or %relMatch%)'
  *
  * @package    core
  * @category   test
@@ -41,8 +68,10 @@ class behat_component_named_replacement {
     /**
      * Create the replacement.
      *
-     * @param string $from
-     * @param string $to
+     * @param string $from this is the old selector that should no longer be used.
+     *      For example 'group_message'.
+     * @param string $to this is the new equivalent that should be used instead.
+     *      For example 'core_message > Message'.
      */
     public function __construct(string $from, string $to) {
         $this->from = $from;
index 70820ac..8b58484 100644 (file)
@@ -15,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Moodle-specific selectors.
+ * Class representing a named selector that can be used in Behat tests.
  *
  * @package    core
  * @category   test
  */
 
 /**
- * Moodle-specific selectors.
+ * Class representing a named selector that can be used in Behat tests.
+ *
+ * Named selectors are what make Behat steps like
+ *   Then I should see "Useful text" in the "General" "fieldset"
+ * Here, "fieldset" is the named selector, and "General" is the locator.
+ *
+ * Selectors can either be exact, in which case the locator needs to
+ * match exactly, or can be partial, for example the way
+ *   When I click "Save" "button"
+ * will trigger a "Save changes" button.
+ *
+ * Instances of this class get returned by the get_exact_named_selectors()
+ * and get_partial_named_selectors() methods in classes like behat_mod_mymod.
+ * The code that makes the magic work is in the trait behat_named_selector
+ * used by both behat_exact_named_selector and behat_partial_named_selector.
  *
  * @package    core
  * @category   test
@@ -44,8 +58,22 @@ class behat_component_named_selector {
     /**
      * Create the selector definition.
      *
+     * As an example, if you define
+     *   new behat_component_named_selector('Message',
+     *           [".//*[@data-conversation-id]//img[contains(@alt, %locator%)]/.."])
+     * in get_partial_named_selectors in behat_message in
+     * message/tests/behat/behat_message.php, then steps like
+     *   When "Group 1" "core_message > Message" should exist
+     * will work.
+     *
+     * Text selectors are things that contain other things (e.g. some particular text), e.g.
+     *   Then I can see "Some text" in the "Whatever" "text_selector"
+     * whereas non-text selectors are atomic things, like
+     *   When I click the "Whatever" "widget".
+     *
      * @param string $alias The 'friendly' name of the thing. This will be prefixed with the component name.
-     * @param array $xpaths A list of xpaths
+     *      For example, if the mod_mymod plugin, says 'Thingy', then "mod_mymod > Thingy" becomes a selector.
+     * @param array $xpaths A list of xpaths one or more XPaths that the selector gets transformed into.
      * @param bool $istextselector Whether this selector can also be used as a text selector.
      */
     public function __construct(string $alias, array $xpaths, bool $istextselector = true) {
index 087b6ec..e683ffc 100644 (file)
 /**
  * Common functions for named selectors.
  *
+ * This has to be a trait, because we need this in both the classes
+ * behat_exact_named_selector and behat_partial_named_selector, and
+ * those classes have to be subclasses of \Behat\Mink\Selector\ExactNamedSelector
+ * and \Behat\Mink\Selector\PartialNamedSelector. This trait is a way achieve
+ * that without duplciated code.
+ *
  * @package    core
  * @category   test
  * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>