MDL-60515 groups: Behat test for viewing the group description.
[moodle.git] / lib / behat / classes / partial_named_selector.php
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/>.
17 /**
18  * Moodle-specific selectors.
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  */
26 /**
27  * Moodle selectors manager.
28  *
29  * @package    core
30  * @category   test
31  * @copyright  2013 David MonllaĆ³
32  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33  */
34 class behat_partial_named_selector extends \Behat\Mink\Selector\PartialNamedSelector {
36     /**
37      * Creates selector instance.
38      */
39     public function __construct() {
40         foreach (self::$customselectors as $alias => $selectors) {
41             $this->registerNamedXpath($alias, implode(' | ', $selectors));
42         }
44         foreach (static::$moodleselectors as $name => $xpath) {
45             $this->registerNamedXpath($name, $xpath);
46         }
48         foreach (self::$customreplacements as $from => $tos) {
49             $this->registerReplacement($from, implode(' or ', $tos));
50         }
52         $this->registerReplacement('%iconMatch%', "(contains(concat(' ', @class, ' '), ' icon ') or name() = 'img')");
53         $this->registerReplacement('%imgAltMatch%', './/*[%iconMatch% and (%altMatch% or %titleMatch%)]');
54         parent::__construct();
55     }
57     /**
58      * @var array Allowed types when using text selectors arguments.
59      */
60     protected static $allowedtextselectors = array(
61         'activity' => 'activity',
62         'block' => 'block',
63         'css_element' => 'css_element',
64         'dialogue' => 'dialogue',
65         'fieldset' => 'fieldset',
66         'icon' => 'icon',
67         'list_item' => 'list_item',
68         'message_area_region' => 'message_area_region',
69         'message_area_region_content' => 'message_area_region_content',
70         'question' => 'question',
71         'region' => 'region',
72         'section' => 'section',
73         'table' => 'table',
74         'table_row' => 'table_row',
75         'xpath_element' => 'xpath_element',
76         'form_row' => 'form_row',
77     );
79     /**
80      * @var array Allowed types when using selector arguments.
81      */
82     protected static $allowedselectors = array(
83         'activity' => 'activity',
84         'block' => 'block',
85         'button' => 'button',
86         'checkbox' => 'checkbox',
87         'css_element' => 'css_element',
88         'dialogue' => 'dialogue',
89         'field' => 'field',
90         'fieldset' => 'fieldset',
91         'file' => 'file',
92         'filemanager' => 'filemanager',
93         'icon' => 'icon',
94         'link' => 'link',
95         'link_or_button' => 'link_or_button',
96         'list_item' => 'list_item',
97         'message_area_action' => 'message_area_action',
98         'message_area_region' => 'message_area_region',
99         'message_area_region_content' => 'message_area_region_content',
100         'optgroup' => 'optgroup',
101         'option' => 'option',
102         'question' => 'question',
103         'radio' => 'radio',
104         'region' => 'region',
105         'section' => 'section',
106         'select' => 'select',
107         'table' => 'table',
108         'table_row' => 'table_row',
109         'text' => 'text',
110         'xpath_element' => 'xpath_element',
111         'form_row' => 'form_row',
112         'autocomplete_selection' => 'autocomplete_selection',
113     );
115     /**
116      * Behat by default comes with XPath, CSS and named selectors,
117      * named selectors are a mapping between names (like button) and
118      * xpaths that represents that names and includes a placeholder that
119      * will be replaced by the locator. These are Moodle's own xpaths.
120      *
121      * @var array XPaths for moodle elements.
122      */
123     protected static $moodleselectors = array(
124         'activity' => <<<XPATH
125 .//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][normalize-space(.) = %locator% ]
126 XPATH
127         , 'block' => <<<XPATH
128 .//*[@data-block][contains(concat(' ', normalize-space(@class), ' '), concat(' ', %locator%, ' ')) or
129      descendant::*[self::h2|self::h3][normalize-space(.) = %locator%]  or
130      @aria-label = %locator%]
131 XPATH
132         , 'dialogue' => <<<XPATH
133 .//div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue ') and
134     normalize-space(descendant::div[
135         contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue-hd ')
136         ]) = %locator%] |
137 .//div[contains(concat(' ', normalize-space(@class), ' '), ' yui-dialog ') and
138     normalize-space(descendant::div[@class='hd']) = %locator%]
139         |
140 .//div[@data-region='modal' and descendant::*[@data-region='title'] = %locator%]
141 XPATH
142         , 'icon' => <<<XPATH
143 .//*[contains(concat(' ', normalize-space(@class), ' '), ' icon ') and ( contains(normalize-space(@title), %locator%))]
144 XPATH
145         , 'list_item' => <<<XPATH
146 .//li[contains(normalize-space(.), %locator%) and not(.//li[contains(normalize-space(.), %locator%)])]
147 XPATH
148         , 'question' => <<<XPATH
149 .//div[contains(concat(' ', normalize-space(@class), ' '), ' que ')]
150     [contains(div[@class='content']/div[contains(concat(' ', normalize-space(@class), ' '), ' formulation ')], %locator%)]
151 XPATH
152         , 'region' => <<<XPATH
153 .//*[self::div | self::section | self::aside | self::header | self::footer][./@id = %locator%]
154 XPATH
155         , 'section' => <<<XPATH
156 .//li[contains(concat(' ', normalize-space(@class), ' '), ' section ')][./descendant::*[self::h3]
157     [normalize-space(.) = %locator%][contains(concat(' ', normalize-space(@class), ' '), ' sectionname ') or
158     contains(concat(' ', normalize-space(@class), ' '), ' section-title ')]] |
159 .//div[contains(concat(' ', normalize-space(@class), ' '), ' sitetopic ')]
160     [./descendant::*[self::h2][normalize-space(.) = %locator%] or %locator% = 'frontpage']
161 XPATH
162         , 'table' => <<<XPATH
163 .//table[(./@id = %locator% or contains(.//caption, %locator%) or contains(.//th, %locator%) or contains(concat(' ', normalize-space(@class), ' '), %locator% ))]
164 XPATH
165         , 'table_row' => <<<XPATH
166 .//tr[contains(normalize-space(.), %locator%) and not(.//tr[contains(normalize-space(.), %locator%)])]
167 XPATH
168         , 'text' => <<<XPATH
169 .//*[contains(., %locator%) and not(.//*[contains(., %locator%)])]
170 XPATH
171         , 'form_row' => <<<XPATH
172 .//*[self::label or self::div[contains(concat(' ', @class, ' '), ' fstaticlabel ')]][contains(., %locator%)]/ancestor::*[contains(concat(' ', @class, ' '), ' fitem ')]
173 XPATH
174         , 'message_area_region' => <<<XPATH
175 .//div[@data-region='messaging-area']/descendant::*[@data-region = %locator%]
176 XPATH
177         , 'message_area_region_content' => <<<XPATH
178 .//div[@data-region='messaging-area']/descendant::*[@data-region-content = %locator%]
179 XPATH
180         , 'message_area_action' => <<<XPATH
181 .//div[@data-region='messaging-area']/descendant::*[@data-action = %locator%]
182 XPATH
183         , 'autocomplete_selection' => <<<XPATH
184 .//div[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-selection', ' '))]/span[@role='listitem'][contains(normalize-space(.), %locator%)]
185 XPATH
186     );
188     protected static $customselectors = [
189         'field' => [
190             'upstream' => <<<XPATH
191 .//*
192 [%fieldFilterWithPlaceholder%][%notFieldTypeFilter%][%fieldMatchWithPlaceholder%]
194 .//label[%tagTextMatch%]//.//*[%fieldFilterWithPlaceholder%][%notFieldTypeFilter%]
196 .//*
197 [%fieldFilterWithoutPlaceholder%][%notFieldTypeFilter%][%fieldMatchWithoutPlaceholder%]
199 .//label[%tagTextMatch%]//.//*[%fieldFilterWithoutPlaceholder%][%notFieldTypeFilter%]
200 XPATH
201         ,
202             'filemanager' => <<<XPATH
203 .//*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']
204     /descendant::input[@id = //label[contains(normalize-space(string(.)), %locator%)]/@for]
205 XPATH
206         ,
207              'passwordunmask' => <<<XPATH
208 .//*[@data-passwordunmask='wrapper']
209     /descendant::input[@id = %locator% or @id = //label[contains(normalize-space(string(.)), %locator%)]/@for]
210 XPATH
211         ],
212     ];
214     /**
215      * Mink comes with a number of named replacements.
216      * Sometimes we want to add our own.
217      *
218      * @var array XPaths for moodle elements.
219      */
220     protected static $customreplacements = [
221         '%buttonMatch%' => [
222             'upstream' => '%idOrNameMatch% or %valueMatch% or %titleMatch%',
223             'aria' => '%ariaLabelMatch%',
224         ],
225         '%ariaLabelMatch%' => [
226             'moodle' => 'contains(./@aria-label, %locator%)',
227         ],
228     ];
230     /**
231      * Allowed selectors getter.
232      *
233      * @return array
234      */
235     public static function get_allowed_selectors() {
236         return static::$allowedselectors;
237     }
239     /**
240      * Allowed text selectors getter.
241      *
242      * @return array
243      */
244     public static function get_allowed_text_selectors() {
245         return static::$allowedtextselectors;
246     }