Merge branch 'MDL-66335' of https://github.com/timhunt/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 14 Oct 2019 16:53:44 +0000 (18:53 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 14 Oct 2019 16:53:44 +0000 (18:53 +0200)
1  2 
lib/behat/behat_base.php
mod/quiz/tests/behat/editing_add_from_question_bank.feature
mod/quiz/tests/behat/editing_add_random.feature

diff --combined lib/behat/behat_base.php
@@@ -35,9 -35,6 +35,9 @@@ use Behat\Mink\Element\NodeElement
  use Behat\Mink\Element\Element;
  use Behat\Mink\Session;
  
 +require_once(__DIR__ . '/classes/component_named_selector.php');
 +require_once(__DIR__ . '/classes/component_named_replacement.php');
 +
  /**
   * Steps definitions base class.
   *
@@@ -219,22 -216,10 +219,22 @@@ class behat_base extends Behat\MinkExte
              $selector = 'xpath';
          }
  
 -        // Convert to named_partial where the selector type is not named_partial, named_exact, xpath, or css.
 +        // Convert to a named selector where the selector type is not a known selector.
          $converttonamed = !$this->getSession()->getSelectorsHandler()->isSelectorRegistered($selector);
          $converttonamed = $converttonamed && 'xpath' !== $selector;
          if ($converttonamed) {
 +            if (behat_partial_named_selector::is_deprecated_selector($selector)) {
 +                if ($replacement = behat_partial_named_selector::get_deprecated_replacement($selector)) {
 +                    error_log("The '{$selector}' selector has been replaced with {$replacement}");
 +                    $selector = $replacement;
 +                }
 +            } else if (behat_exact_named_selector::is_deprecated_selector($selector)) {
 +                if ($replacement = behat_exact_named_selector::get_deprecated_replacement($selector)) {
 +                    error_log("The '{$selector}' selector has been replaced with {$replacement}");
 +                    $selector = $replacement;
 +                }
 +            }
 +
              $allowedpartialselectors = behat_partial_named_selector::get_allowed_selectors();
              $allowedexactselectors = behat_exact_named_selector::get_allowed_selectors();
              if (isset($allowedpartialselectors[$selector])) {
                  $locator = behat_selectors::normalise_named_selector($allowedexactselectors[$selector], $locator);
                  $selector = 'named_exact';
              } else {
 -                throw new ExpectationException("The '{$selector}' selector type is not registered.", $this);
 +                throw new ExpectationException("The '{$selector}' selector type is not registered.", $this->getSession()->getDriver());
              }
          }
  
          }
      }
  
+     /**
+      * Convert page names to URLs for steps like 'When I am on the "[page name]" page'.
+      *
+      * You should override this as appropriate for your plugin. The method
+      * {@link behat_navigation::resolve_core_page_url()} is a good example.
+      *
+      * Your overridden method should document the recognised page types with
+      * a table like this:
+      *
+      * Recognised page names are:
+      * | Page            | Description                                                    |
+      *
+      * @param string $page name of the page, with the component name removed e.g. 'Admin notification'.
+      * @return moodle_url the corresponding URL.
+      * @throws Exception with a meaningful error message if the specified page cannot be found.
+      */
+     protected function resolve_page_url(string $page): moodle_url {
+         throw new Exception('Component "' . get_class($this) .
+                 '" does not support the generic \'When I am on the "' . $page .
+                 '" page\' navigation step.');
+     }
+     /**
+      * Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'.
+      *
+      * A typical example might be:
+      *     When I am on the "Test quiz" "mod_quiz > Responses report" page
+      * which would cause this method in behat_mod_quiz to be called with
+      * arguments 'Responses report', 'Test quiz'.
+      *
+      * You should override this as appropriate for your plugin. The method
+      * {@link behat_navigation::resolve_core_page_instance_url()} is a good example.
+      *
+      * Your overridden method should document the recognised page types with
+      * a table like this:
+      *
+      * Recognised page names are:
+      * | Type      | identifier meaning | Description                                     |
+      *
+      * @param string $type identifies which type of page this is, e.g. 'Attempt review'.
+      * @param string $identifier identifies the particular page, e.g. 'Test quiz > student > Attempt 1'.
+      * @return moodle_url the corresponding URL.
+      * @throws Exception with a meaningful error message if the specified page cannot be found.
+      */
+     protected function resolve_page_instance_url(string $type, string $identifier): moodle_url {
+         throw new Exception('Component "' . get_class($this) .
+                 '" does not support the generic \'When I am on the "' . $identifier .
+                 '" "' . $type . '" page\' navigation step.');
+     }
      /**
       * Gets the required timeout in seconds.
       *
      public static function get_extended_timeout() : int {
          return self::get_real_timeout(10);
      }
 +
 +    /**
 +     * 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 {
 +        return [];
 +    }
 +
 +    /**
 +     * 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 {
 +        return [];
 +    }
 +
 +    /**
 +     * 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[]
 +     */
 +    public static function get_named_replacements(): array {
 +        return [];
 +    }
  }
@@@ -21,9 -21,9 +21,9 @@@ Feature: Adding questions to a quiz fro
        | contextlevel | reference | name           |
        | Course       | C1        | Test questions |
      And the following "questions" exist:
 -      | questioncategory | qtype     | name             | user     | questiontext     |
 -      | Test questions   | essay     | question 01 name | admin    | Question 01 text |
 -      | Test questions   | essay     | question 02 name | teacher1 | Question 02 text |
 +      | questioncategory | qtype     | name             | user     | questiontext     | idnumber |
 +      | Test questions   | essay     | question 01 name | admin    | Question 01 text |          |
 +      | Test questions   | essay     | question 02 name | teacher1 | Question 02 text | qidnum   |
  
    Scenario: The questions can be filtered by tag
      Given I log in as "teacher1"
      And I set the following fields to these values:
        | Tags | bar |
      And I press "id_submitbutton"
-     And I am on "Course 1" course homepage
-     And I follow "Quiz 1"
-     And I navigate to "Edit quiz" in current page administration
+     And I am on the "Quiz 1" "mod_quiz > Edit" page
      And I open the "last" add to quiz menu
      And I follow "from question bank"
 +    Then I should see "foo" in the "question 01 name" "table_row"
 +    And I should see "bar" in the "question 02 name" "table_row"
 +    And I should see "qidnum" in the "question 02 name" "table_row"
      And I set the field "Filter by tags..." to "foo"
      And I press key "13" in the field "Filter by tags..."
 -    Then I should see "question 01 name" in the "categoryquestions" "table"
 +    And I should see "question 01 name" in the "categoryquestions" "table"
      And I should not see "question 02 name" in the "categoryquestions" "table"
  
    Scenario: The question modal can be paginated
@@@ -74,9 -69,7 +72,7 @@@
        | Test questions   | essay     | question 21 name | teacher1 | Question 21 text |
        | Test questions   | essay     | question 22 name | teacher1 | Question 22 text |
      And I log in as "teacher1"
-     And I am on "Course 1" course homepage
-     And I follow "Quiz 1"
-     And I navigate to "Edit quiz" in current page administration
+     And I am on the "Quiz 1" "mod_quiz > Edit" page
      And I open the "last" add to quiz menu
      And I follow "from question bank"
      And I click on "2" "link" in the ".pagination" "css_element"
        | Section 1 | 1         | 0       |
        | Section 2 | 2         | 0       |
      And I log in as "teacher1"
-     And I am on "Course 1" course homepage
-     And I follow "Quiz 1"
-     When I navigate to "Edit quiz" in current page administration
-     And I open the "Page 1" add to quiz menu
+     And I am on the "Quiz 1" "mod_quiz > Edit" page
+     When I open the "Page 1" add to quiz menu
      And I follow "from question bank"
      And I set the field with xpath "//tr[contains(normalize-space(.), 'question 03 name')]//input[@type='checkbox']" to "1"
      And I click on "Add selected questions to the quiz" "button"
@@@ -35,12 -35,10 +35,10 @@@ Feature: Adding random questions to a q
        | Tags | foo |
      And I press "id_submitbutton"
      And I click on "Manage tags" "link" in the "question 2 name" "table_row"
 -    And I set the following fields to these values:
 +    And I set the following fields in the "Question tags" "dialogue" to these values:
        | Tags | bar |
      And I press "Save changes"
-     And I am on "Course 1" course homepage
-     And I follow "Quiz 1"
-     And I navigate to "Edit quiz" in current page administration
+     And I am on the "Quiz 1" "mod_quiz > Edit" page
      And I open the "last" add to quiz menu
      And I follow "a random question"
      And I open the autocomplete suggestions list
@@@ -52,8 -50,6 +50,6 @@@
        | capability             | permission | role           | contextlevel | reference |
        | moodle/question:useall | Prevent    | editingteacher | Course       | C1        |
      And I log in as "teacher1"
-     And I am on "Course 1" course homepage
-     And I follow "Quiz 1"
-     And I navigate to "Edit quiz" in current page administration
+     And I am on the "Quiz 1" "mod_quiz > Edit" page
      When I open the "last" add to quiz menu
      Then I should not see "a random question"