| Línea 12... |
Línea 12... |
| 12 |
// GNU General Public License for more details.
|
12 |
// GNU General Public License for more details.
|
| 13 |
//
|
13 |
//
|
| 14 |
// You should have received a copy of the GNU General Public License
|
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/>.
|
15 |
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
| Línea 16... |
Línea -... |
| 16 |
|
- |
|
| 17 |
/**
|
16 |
|
| 18 |
* Steps definitions to open and close action menus.
|
- |
|
| 19 |
*
|
- |
|
| 20 |
* @package core
|
- |
|
| 21 |
* @category test
|
17 |
use Behat\Mink\Exception\DriverException;
|
| 22 |
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
|
- |
|
| 23 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
- |
|
| 24 |
*/
|
- |
|
| 25 |
|
18 |
use Behat\Mink\Exception\ExpectationException;
|
| Línea 26... |
Línea 19... |
| 26 |
use Behat\Mink\Exception\{DriverException, ExpectationException};
|
19 |
use Behat\Mink\Element\NodeElement;
|
| Línea 27... |
Línea 20... |
| 27 |
|
20 |
|
| Línea 36... |
Línea 29... |
| 36 |
* @category test
|
29 |
* @category test
|
| 37 |
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
|
30 |
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
|
| 38 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
31 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
| 39 |
*/
|
32 |
*/
|
| 40 |
class behat_accessibility extends behat_base {
|
33 |
class behat_accessibility extends behat_base {
|
| 41 |
|
- |
|
| 42 |
/**
|
34 |
/**
|
| 43 |
* Run the axe-core accessibility tests.
|
35 |
* Run the axe-core accessibility tests.
|
| 44 |
*
|
36 |
*
|
| 45 |
* There are standard tags to ensure WCAG 2.1 A, WCAG 2.1 AA, and Section 508 compliance.
|
37 |
* There are standard tags to ensure WCAG 2.1 A, WCAG 2.1 AA, and Section 508 compliance.
|
| 46 |
* It is also possible to specify any desired optional tags.
|
38 |
* It is also possible to specify any desired optional tags.
|
| 47 |
*
|
39 |
*
|
| 48 |
* The list of available tags can be found at
|
- |
|
| 49 |
* https://github.com/dequelabs/axe-core/blob/v4.8.4/doc/rule-descriptions.md.
|
40 |
* See {@link https://github.com/dequelabs/axe-core/blob/v4.10.2/doc/rule-descriptions.md} for the list of available tags
|
| 50 |
*
|
41 |
*
|
| 51 |
* @Then the page should meet accessibility standards
|
42 |
* @Then the page should meet accessibility standards
|
| 52 |
* @Then the page should meet accessibility standards with :extratags extra tests
|
43 |
* @Then the page should meet accessibility standards with :extratags extra tests
|
| 53 |
* @Then the page should meet :standardtags accessibility standards
|
44 |
* @Then the page should meet :standardtags accessibility standards
|
| 54 |
* @param string $standardtags Comma-separated list of standard tags to run
|
45 |
* @param string $standardtags Comma-separated list of standard tags to run
|
| Línea 61... |
Línea 52... |
| 61 |
array_filter(array_map('trim', explode(',', $extratags)))
|
52 |
array_filter(array_map('trim', explode(',', $extratags)))
|
| 62 |
);
|
53 |
);
|
| 63 |
}
|
54 |
}
|
| Línea 64... |
Línea 55... |
| 64 |
|
55 |
|
| - |
|
56 |
/**
|
| - |
|
57 |
* Run the axe-core accessibility tests for a page region.
|
| - |
|
58 |
*
|
| - |
|
59 |
* There are standard tags to ensure WCAG 2.1 A, WCAG 2.1 AA, and Section 508 compliance.
|
| - |
|
60 |
* It is also possible to specify any desired optional tags.
|
| - |
|
61 |
*
|
| - |
|
62 |
* See {@link https://github.com/dequelabs/axe-core/blob/v4.10.0/doc/rule-descriptions.md} for the list of available tags
|
| - |
|
63 |
*
|
| - |
|
64 |
* @Then the :element :selector should meet accessibility standards
|
| - |
|
65 |
* @Then the :element :selector should meet accessibility standards with :extratags extra tests
|
| - |
|
66 |
* @Then the :element :selector should meet :standardtags accessibility standards
|
| - |
|
67 |
* @param string $element The element to run the tests on
|
| - |
|
68 |
* @param string $selector The selector to use to find the element
|
| - |
|
69 |
* @param string $standardtags Comma-separated list of standard tags to run
|
| - |
|
70 |
* @param string $extratags Comma-separated list of tags to run in addition to the standard tags
|
| - |
|
71 |
*/
|
| - |
|
72 |
public function run_axe_validation_for_tags_within_element(
|
| - |
|
73 |
string $element,
|
| - |
|
74 |
string $selector,
|
| - |
|
75 |
string $standardtags = '',
|
| - |
|
76 |
string $extratags = '',
|
| - |
|
77 |
): void {
|
| - |
|
78 |
$node = $this->get_selected_node($selector, $element);
|
| - |
|
79 |
$this->run_axe_for_tags(
|
| - |
|
80 |
// Turn the comma-separated string into an array of trimmed values, filtering out empty values.
|
| - |
|
81 |
array_filter(array_map('trim', explode(',', $standardtags))),
|
| - |
|
82 |
array_filter(array_map('trim', explode(',', $extratags))),
|
| - |
|
83 |
$node,
|
| - |
|
84 |
);
|
| - |
|
85 |
}
|
| - |
|
86 |
|
| 65 |
/**
|
87 |
/**
|
| 66 |
* Run the Axe tests.
|
88 |
* Run the Axe tests.
|
| 67 |
*
|
89 |
*
|
| 68 |
* See https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md for details of the supported
|
- |
|
| 69 |
* tags.
|
90 |
* See {@see behat_accessibility::run_axe_validation_for_tags} for details of the supported tags.
|
| 70 |
*
|
91 |
*
|
| 71 |
* @param array $standardtags The list of standard tags to run
|
92 |
* @param array $standardtags The list of standard tags to run
|
| - |
|
93 |
* @param array $extratags The list of tags, in addition to the standard tags, to run
|
| 72 |
* @param array $extratags The list of tags, in addition to the standard tags, to run
|
94 |
* @param null|NodeElement $containerelement The element to run the tests on
|
| 73 |
*/
|
95 |
*/
|
| - |
|
96 |
protected function run_axe_for_tags(
|
| - |
|
97 |
array $standardtags = [],
|
| - |
|
98 |
array $extratags = [],
|
| - |
|
99 |
?NodeElement $containerelement = null,
|
| 74 |
protected function run_axe_for_tags(array $standardtags = [], array $extratags = []): void {
|
100 |
): void {
|
| 75 |
if (!behat_config_manager::get_behat_run_config_value('axe')) {
|
101 |
if (!behat_config_manager::get_behat_run_config_value('axe')) {
|
| 76 |
return;
|
102 |
return;
|
| Línea 77... |
Línea 103... |
| 77 |
}
|
103 |
}
|
| Línea 84... |
Línea 110... |
| 84 |
|
110 |
|
| Línea 85... |
Línea 111... |
| 85 |
$this->require_javascript();
|
111 |
$this->require_javascript();
|
| 86 |
|
112 |
|
| - |
|
113 |
$axeurl = (new \moodle_url('/lib/behat/axe/axe.min.js'))->out(false);
|
| - |
|
114 |
$axeconfig = $this->get_axe_config_for_tags($standardtags, $extratags);
|
| - |
|
115 |
$xpath = '';
|
| - |
|
116 |
if ($containerelement) {
|
| 87 |
$axeurl = (new \moodle_url('/lib/behat/axe/axe.min.js'))->out(false);
|
117 |
$xpath = $this->prepare_xpath_for_javascript($containerelement->getXpath());
|
| 88 |
$axeconfig = $this->get_axe_config_for_tags($standardtags, $extratags);
|
118 |
}
|
| 89 |
$runaxe = <<<EOF
|
119 |
$runaxe = <<<EOF
|
| 90 |
(axeurl => {
|
120 |
(axeurl => {
|
| 91 |
const runTests = () => {
|
121 |
const runTests = () => {
|
| Línea -... |
Línea 122... |
| - |
|
122 |
const axeTag = document.querySelector('script[data-purpose="axe"]');
|
| - |
|
123 |
axeTag.dataset.results = null;
|
| - |
|
124 |
|
| - |
|
125 |
const getRun = () => {
|
| - |
|
126 |
const xpath = "{$xpath}";
|
| - |
|
127 |
if (xpath.length) {
|
| - |
|
128 |
const targetElements = [];
|
| - |
|
129 |
const results = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
|
| - |
|
130 |
let targetElement = results.iterateNext();
|
| - |
|
131 |
while (targetElement) {
|
| - |
|
132 |
targetElements.push(targetElement);
|
| - |
|
133 |
targetElement = results.iterateNext();
|
| - |
|
134 |
}
|
| 92 |
const axeTag = document.querySelector('script[data-purpose="axe"]');
|
135 |
return axe.run(targetElements, {$axeconfig});
|
| - |
|
136 |
}
|
| - |
|
137 |
|
| - |
|
138 |
return axe.run({$axeconfig});
|
| 93 |
axeTag.dataset.results = null;
|
139 |
};
|
| 94 |
|
140 |
|
| 95 |
axe.run({$axeconfig})
|
141 |
getRun()
|
| 96 |
.then(results => {
|
142 |
.then(results => {
|
| 97 |
axeTag.dataset.results = JSON.stringify({
|
143 |
axeTag.dataset.results = JSON.stringify({
|
| Línea 165... |
Línea 211... |
| 165 |
implode("\n ", $node->target)
|
211 |
implode("\n ", $node->target)
|
| 166 |
);
|
212 |
);
|
| 167 |
}
|
213 |
}
|
| Línea 168... |
Línea 214... |
| 168 |
|
214 |
|
| 169 |
$violationdata .= sprintf(
|
215 |
$violationdata .= sprintf(
|
| 170 |
" %.03d violations of '%s' (severity: %s)\n%s\n",
|
216 |
" %.03d violations of rule '%s' found (severity: %s)\n",
|
| 171 |
count($violation->nodes),
|
217 |
count($violation->nodes),
|
| 172 |
$violation->description,
|
218 |
$violation->id,
|
| 173 |
$violation->impact,
|
- |
|
| 174 |
$nodedata
|
219 |
$violation->impact,
|
| - |
|
220 |
);
|
| - |
|
221 |
$violationdata .= " {$violation->help}\n";
|
| - |
|
222 |
$violationdata .= " {$violation->description}\n";
|
| - |
|
223 |
$violationdata .= " {$violation->helpUrl}\n";
|
| 175 |
);
|
224 |
$violationdata .= $nodedata;
|
| Línea 176... |
Línea 225... |
| 176 |
}
|
225 |
}
|
| 177 |
|
226 |
|
| Línea 178... |
Línea 227... |
| 178 |
throw new ExpectationException($violationdata, $this->getSession());
|
227 |
throw new ExpectationException($violationdata, $this->getSession());
|
| 179 |
}
|
228 |
}
|
| 180 |
|
229 |
|
| 181 |
/**
|
230 |
/**
|
| 182 |
* Get the configuration to use with Axe.
|
231 |
* Get the configuration to use with Axe.
|
| 183 |
*
|
232 |
*
|
| 184 |
* See https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md for details of the rules.
|
233 |
* See {@see behat_accessibility::run_axe_validation_for_tags} for details of the rules.
|
| 185 |
*
|
234 |
*
|
| 186 |
* @param array|null $standardtags The list of standard tags to run
|
235 |
* @param array|null $standardtags The list of standard tags to run
|
| 187 |
* @param array|null $extratags The list of tags, in addition to the standard tags, to run
|
236 |
* @param array|null $extratags The list of tags, in addition to the standard tags, to run
|
| 188 |
* @return string The JSON-encoded configuration.
|
237 |
* @return string The JSON-encoded configuration.
|
| 189 |
*/
|
238 |
*/
|
| 190 |
protected function get_axe_config_for_tags(?array $standardtags = null, ?array $extratags = null): string {
|
239 |
protected function get_axe_config_for_tags(?array $standardtags = null, ?array $extratags = null): string {
|
| - |
|
240 |
if (empty($standardtags)) {
|
| - |
|
241 |
$standardtags = [
|
| 191 |
if (empty($standardtags)) {
|
242 |
// Meet WCAG 2.2 Level A success criteria.
|
| Línea 192... |
Línea 243... |
| 192 |
$standardtags = [
|
243 |
'wcag2a',
|
| - |
|
244 |
'wcag21a',
|
| - |
|
245 |
'wcag22a',
|
| 193 |
// Meet WCAG 2.2 Level A success criteria.
|
246 |
|
| Línea 194... |
Línea 247... |
| 194 |
'wcag22a',
|
247 |
// Meet WCAG 2.2 Level AA success criteria.
|
| 195 |
|
248 |
'wcag2aa',
|
| 196 |
// Meet WCAG 2.2 Level AA success criteria.
|
249 |
'wcag21aa',
|