MDL-84595 tool_behat: Allow accessibility tests to run for a single Node
This commit is contained in:
@@ -1676,4 +1676,19 @@ EOF;
|
||||
|
||||
return $result ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare an xpath for insertion into Selenium JavaScript.
|
||||
*
|
||||
* @param string $xpath
|
||||
* @return string
|
||||
*/
|
||||
protected function prepare_xpath_for_javascript(string $xpath): string {
|
||||
$newlines = [
|
||||
"\r\n",
|
||||
"\r",
|
||||
"\n",
|
||||
];
|
||||
return str_replace($newlines, ' ', $xpath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,16 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Steps definitions to open and close action menus.
|
||||
*
|
||||
* @package core
|
||||
* @category test
|
||||
* @copyright 2020 Andrew Nicols <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use Behat\Mink\Exception\{DriverException, ExpectationException};
|
||||
use Behat\Mink\Exception\DriverException;
|
||||
use Behat\Mink\Exception\ExpectationException;
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
@@ -38,7 +31,6 @@ require_once(__DIR__ . '/../../behat/behat_base.php');
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_accessibility extends behat_base {
|
||||
|
||||
/**
|
||||
* Run the axe-core accessibility tests.
|
||||
*
|
||||
@@ -62,6 +54,37 @@ class behat_accessibility extends behat_base {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the axe-core accessibility tests for a page region.
|
||||
*
|
||||
* There are standard tags to ensure WCAG 2.1 A, WCAG 2.1 AA, and Section 508 compliance.
|
||||
* It is also possible to specify any desired optional tags.
|
||||
*
|
||||
* See {@link https://github.com/dequelabs/axe-core/blob/v4.10.0/doc/rule-descriptions.md} for the list of available tags
|
||||
*
|
||||
* @Then the :element :selector should meet accessibility standards
|
||||
* @Then the :element :selector should meet accessibility standards with :extratags extra tests
|
||||
* @Then the :element :selector should meet :standardtags accessibility standards
|
||||
* @param string $element The element to run the tests on
|
||||
* @param string $selector The selector to use to find the element
|
||||
* @param string $standardtags Comma-separated list of standard tags to run
|
||||
* @param string $extratags Comma-separated list of tags to run in addition to the standard tags
|
||||
*/
|
||||
public function run_axe_validation_for_tags_within_element(
|
||||
string $element,
|
||||
string $selector,
|
||||
string $standardtags = '',
|
||||
string $extratags = '',
|
||||
): void {
|
||||
$node = $this->get_selected_node($selector, $element);
|
||||
$this->run_axe_for_tags(
|
||||
// Turn the comma-separated string into an array of trimmed values, filtering out empty values.
|
||||
array_filter(array_map('trim', explode(',', $standardtags))),
|
||||
array_filter(array_map('trim', explode(',', $extratags))),
|
||||
$node,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the Axe tests.
|
||||
*
|
||||
@@ -70,8 +93,13 @@ class behat_accessibility extends behat_base {
|
||||
*
|
||||
* @param array $standardtags The list of standard tags to run
|
||||
* @param array $extratags The list of tags, in addition to the standard tags, to run
|
||||
* @param null|NodeElement $containerelement The element to run the tests on
|
||||
*/
|
||||
protected function run_axe_for_tags(array $standardtags = [], array $extratags = []): void {
|
||||
protected function run_axe_for_tags(
|
||||
array $standardtags = [],
|
||||
array $extratags = [],
|
||||
?NodeElement $containerelement = null,
|
||||
): void {
|
||||
if (!behat_config_manager::get_behat_run_config_value('axe')) {
|
||||
return;
|
||||
}
|
||||
@@ -86,13 +114,33 @@ class behat_accessibility extends behat_base {
|
||||
|
||||
$axeurl = (new \moodle_url('/lib/behat/axe/axe.min.js'))->out(false);
|
||||
$axeconfig = $this->get_axe_config_for_tags($standardtags, $extratags);
|
||||
$xpath = '';
|
||||
if ($containerelement) {
|
||||
$xpath = $this->prepare_xpath_for_javascript($containerelement->getXpath());
|
||||
}
|
||||
$runaxe = <<<EOF
|
||||
(axeurl => {
|
||||
const runTests = () => {
|
||||
const axeTag = document.querySelector('script[data-purpose="axe"]');
|
||||
axeTag.dataset.results = null;
|
||||
|
||||
axe.run({$axeconfig})
|
||||
const getRun = () => {
|
||||
const xpath = "{$xpath}";
|
||||
if (xpath.length) {
|
||||
const targetElements = [];
|
||||
const results = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
|
||||
let targetElement = results.iterateNext();
|
||||
while (targetElement) {
|
||||
targetElements.push(targetElement);
|
||||
targetElement = results.iterateNext();
|
||||
}
|
||||
return axe.run(targetElements, {$axeconfig});
|
||||
}
|
||||
|
||||
return axe.run({$axeconfig});
|
||||
};
|
||||
|
||||
getRun()
|
||||
.then(results => {
|
||||
axeTag.dataset.results = JSON.stringify({
|
||||
violations: results.violations,
|
||||
|
||||
@@ -977,13 +977,12 @@ class behat_general extends behat_base {
|
||||
list($preselector, $prelocator) = $this->transform_selector($preselectortype, $preelement);
|
||||
list($postselector, $postlocator) = $this->transform_selector($postselectortype, $postelement);
|
||||
|
||||
$newlines = [
|
||||
"\r\n",
|
||||
"\r",
|
||||
"\n",
|
||||
];
|
||||
$prexpath = str_replace($newlines, ' ', $this->find($preselector, $prelocator, false, $containernode)->getXpath());
|
||||
$postxpath = str_replace($newlines, ' ', $this->find($postselector, $postlocator, false, $containernode)->getXpath());
|
||||
$prexpath = $this->prepare_xpath_for_javascript(
|
||||
$this->find($preselector, $prelocator, false, $containernode)->getXpath()
|
||||
);
|
||||
$postxpath = $this->prepare_xpath_for_javascript(
|
||||
$this->find($postselector, $postlocator, false, $containernode)->getXpath()
|
||||
);
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
// The xpath to do this was running really slowly on certain Chrome versions so we are using
|
||||
|
||||
Reference in New Issue
Block a user