[TOOLS][DOCKER][A11Y] Switch to Pa11y CI and don't run it 'integrated' with codeception, since there was no good way to share cookies
This commit is contained in:
parent
d542be1df4
commit
a59997b41f
4
Makefile
4
Makefile
|
@ -45,8 +45,8 @@ stop-tooling: .PHONY
|
||||||
tooling-php-shell: tooling-docker
|
tooling-php-shell: tooling-docker
|
||||||
docker exec -it $(call translate-container-name,tooling_php_1) sh
|
docker exec -it $(call translate-container-name,tooling_php_1) sh
|
||||||
|
|
||||||
acceptance-and-accessibility: tooling-docker
|
test-accesibility: tooling-docker
|
||||||
docker exec -it $(call translate-container-name,tooling_php_1) /var/tooling/acceptance_and_accessibility.sh
|
cd docker/tooling && docker-compose run pa11y /usr/local/bin/pa11y-ci -c /pa11y/config.json
|
||||||
|
|
||||||
test: tooling-docker
|
test: tooling-docker
|
||||||
docker exec $(call translate-container-name,tooling_php_1) /var/tooling/coverage.sh $(call args,'')
|
docker exec $(call translate-container-name,tooling_php_1) /var/tooling/coverage.sh $(call args,'')
|
||||||
|
|
|
@ -6,7 +6,6 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- redis
|
- redis
|
||||||
- pa11y
|
|
||||||
volumes:
|
volumes:
|
||||||
# Entrypoint
|
# Entrypoint
|
||||||
- ../php/entrypoint.sh:/entrypoint.sh
|
- ../php/entrypoint.sh:/entrypoint.sh
|
||||||
|
@ -45,8 +44,10 @@ services:
|
||||||
|
|
||||||
pa11y:
|
pa11y:
|
||||||
build: pa11y
|
build: pa11y
|
||||||
|
depends_on:
|
||||||
|
- nginx
|
||||||
volumes:
|
volumes:
|
||||||
- ../../tests/CodeCeption/pa11y-config.json:/pa11y/config.json
|
- ../../tests/pa11y-ci-config.json:/pa11y/config.json
|
||||||
cap_add:
|
cap_add:
|
||||||
- SYS_ADMIN
|
- SYS_ADMIN
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
FROM node
|
FROM node
|
||||||
|
|
||||||
RUN apt-get update && apt-get -y install npm openssh-server && npm install -g pa11y
|
RUN apt-get update && apt-get install -y \
|
||||||
|
apt-transport-https ca-certificates curl fontconfig \
|
||||||
|
fonts-ipafont-gothic fonts-kacst fonts-liberation fonts-thai-tlwg \
|
||||||
|
fonts-wqy-zenhei gconf-service libgbm-dev libasound2 \
|
||||||
|
libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 \
|
||||||
|
libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
|
||||||
|
libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 \
|
||||||
|
libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 \
|
||||||
|
libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
|
||||||
|
libxtst6 locales lsb-release unzip xdg-utils wget \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& apt-get autoremove -q \
|
||||||
|
&& npm install -g pa11y-ci
|
||||||
|
|
||||||
COPY sshd_config /etc/ssh/sshd_config
|
RUN useradd -ms /bin/bash puppet
|
||||||
RUN echo 'root:pa11y' | chpasswd
|
USER puppet
|
||||||
|
|
||||||
ENTRYPOINT service ssh start && sleep infinity
|
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A helper class for Codeception (http://codeception.com/) that allows automated accessility checks
|
|
||||||
* (WCAG 2.0, Section508) using the pa11y (http://pa11y.org/) command line tool
|
|
||||||
* during acceptance testing.
|
|
||||||
* It uses local binaries and can therefore be run offline.
|
|
||||||
*
|
|
||||||
* Requirements:
|
|
||||||
* =============
|
|
||||||
*
|
|
||||||
* - Codeception with WebDriver or PhpBrowser set up
|
|
||||||
* - pa11y is installed locally (e.g. using "npm insgall -g pa11y")
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Installation:
|
|
||||||
* =============
|
|
||||||
*
|
|
||||||
* - Copy this file to _support/Helper/ in the codeception directory
|
|
||||||
* - Merge the following configuration to acceptance.suite.yml:
|
|
||||||
*
|
|
||||||
* modules:
|
|
||||||
* enabled:
|
|
||||||
* - \Helper\AccessibilityValidator
|
|
||||||
* config:
|
|
||||||
* \Helper\AccessibilityValidator:
|
|
||||||
* pa11yPath: /usr/local/bin/pa11y
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* ======
|
|
||||||
*
|
|
||||||
* Validate the current site against WCAG 2.0 (AAA):
|
|
||||||
* $I->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 <tobias@hoessl.eu>
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"chromeLaunchConfig": {
|
|
||||||
"args": ["--no-sandbox"]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"chromeLaunchConfig": {
|
|
||||||
"args": ["--no-sandbox"],
|
|
||||||
"ignoreHTTPSErrors": true
|
|
||||||
}
|
|
||||||
}
|
|
24
tests/pa11y-ci-config.json
Normal file
24
tests/pa11y-ci-config.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"defaults": {
|
||||||
|
"chromeLaunchConfig": {
|
||||||
|
"ignoreHTTPSErrors": true
|
||||||
|
},
|
||||||
|
"timeout": 5000,
|
||||||
|
"viewport": {
|
||||||
|
"width": 320,
|
||||||
|
"height": 480
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"concurrency": 4,
|
||||||
|
"urls": [
|
||||||
|
"https://nginx/",
|
||||||
|
"https://nginx/feed/public",
|
||||||
|
"https://nginx/doc/faq",
|
||||||
|
"https://nginx/doc/tos",
|
||||||
|
"https://nginx/doc/privacy",
|
||||||
|
"https://nginx/doc/source",
|
||||||
|
"https://nginx/doc/version",
|
||||||
|
"https://nginx/main/login",
|
||||||
|
"https://nginx/main/register"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user