validatePa11y(\Helper\AccessibilityValidator::STANDARD_WCAG2AAA); * * Validate the current site against WCAG 2.0 (AA): * $I->validatePa11y(); // or: * $I->validatePa11y(\Helper\AccessibilityValidator::STANDARD_WCAG2A); * * Validate the current site against WCAG 2.0 (A): * $I->validatePa11y(\Helper\AccessibilityValidator::STANDARD_WCAG2A); * * Validate the current site against Section 508: * $I->validatePa11y(\Helper\AccessibilityValidator::STANDARD_SECTION508); * * Validate against WCAG 2.0 (AA), but ignore errors containing the string "Ignoreme": * $I->validatePa11y(\Helper\AccessibilityValidator::STANDARD_WCAG2A, ["Ignoreme"]); * * @license http://www.opensource.org/licenses/mit-license.html MIT License * @author Tobias Hößl */ namespace Helper; use Exception; use PHPUnit\Framework\Assert; class AccessibilityValidator extends \Codeception\Module { public static $SUPPORTED_STANDARDS = [ 'WCAG2AAA', 'WCAG2AA', 'WCAG2A', 'Section508', ]; public const STANDARD_WCAG2AAA = 'WCAG2AAA'; public const STANDARD_WCAG2AA = 'WCAG2AA'; public const STANDARD_WCAG2A = 'WCAG2A'; public const STANDARD_SECTION508 = 'Section508'; private function getPageUrl(): string { if ($this->hasModule('WebDriver')) { /** @var \Codeception\Module\WebDriver $webdriver */ $webdriver = $this->getModule('WebDriver'); return $webdriver->webDriver->getCurrentURL(); } else { /** @var \Codeception\Module\PhpBrowser $phpBrowser */ $phpBrowser = $this->getModule('PhpBrowser'); return trim($phpBrowser->_getUrl(), '/') . $phpBrowser->_getCurrentUri(); } } /** * @throws Exception */ private function validateByPa11y(string $url, string $standard): array { if (!\in_array($standard, static::$SUPPORTED_STANDARDS)) { throw new Exception('Unknown standard: ' . $standard); } exec('sshpass -p pa11y ssh -o StrictHostKeyChecking=no pa11y 2>/dev/null pa11y -c /pa11y/config.json' . ' -s ' . $standard . " -r json '" . addslashes($url) . "'", $output); if (!empty($output)) { $data = json_decode($output[0], true); if (!$data) { throw new Exception('Invalid data returned from validation service: ' . implode("\n", $output)); } return $data; } return []; } /** * @param string[] $ignoreMessages */ public function validatePa11y(string $standard = 'WCAG2AA', array $ignoreMessages = []): void { try { $url = $this->getPageUrl(); $messages = $this->validateByPa11y($url, $standard); } catch (Exception $e) { $this->fail($e->getMessage()); return; } $failMessages = []; foreach ($messages as $message) { if ($message['type'] == 'error') { $string = $message['code'] . "\n" . $message['selector'] . ': '; $string .= $message['context'] . "\n"; $string .= $message['message']; $ignoring = false; foreach ($ignoreMessages as $ignoreMessage) { if (mb_stripos($string, $ignoreMessage) !== false) { $ignoring = true; } } if (!$ignoring) { $failMessages[] = $string; } } } if (\count($failMessages) > 0) { $failStr = 'Failed ' . $standard . ' check: ' . "\n"; $failStr .= implode("\n\n", $failMessages); Assert::fail($failStr); } } }