Compare commits

...

5 Commits

Author SHA1 Message Date
dependabot[bot]
ee6c79f70a Bump minimatch and mocha
Bumps [minimatch](https://github.com/isaacs/minimatch) to 3.1.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `minimatch` from 3.0.4 to 3.1.2
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

Updates `mocha` from 7.2.0 to 10.2.0
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v7.2.0...v10.2.0)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-12 16:08:02 +00:00
Danyal Aytekin
e55cae4786 In workflow, update default branch to main, use ubuntu-20.04 (#315)
* Update default branch name to `main`

* Use `ubuntu-20.04` for build, until this project upgrades to `pa11y-webservice@5`
2023-11-12 15:52:09 +00:00
Sangita Mane
5202f59008 A11y fixes for pa11y dashboard pages. (#306)
* First draft of a11y fixes.

* Amended results title

* Amended results title (again)

* Back to top keyboard operation

Removed the 'data-role="top"' attribute, which implemented a cool animation to scroll to top but prevented the default behaviour, resulting in the keyboard focus not going back to top.

* Options Button

Fix to have a working options button, but using the mouse only. This is not a good solution because it cannot be operated via the keyboard.

* Fixed options menu css.

* Results view layout changes

* Undoing layout changes

* Graph layout fixes.

* Skip Rules Link

Added a link to skip the list of rules, which can get very long and annoying for any keyboard user not interested in selecting a rule. Most probably, implementing a collapsible list of rules would be a better solution here.

Co-authored-by: Carlos Muncharaz <carlos@muncharaz.eu>
2022-10-11 14:17:43 +02:00
Jose Bolos
b9b049ec2b Address all eslint warnings
Address all eslint warnings that were still present by:

* Extracting code to a new function in order to reduce complexity
* Renamed error variables and use shorthand notation for objects
* Disabling eslint warnings where addressing the issue would require too much refactoring
2022-04-11 17:27:15 +02:00
Jose Bolos
0e7849dd07 Add issue template 2022-04-08 14:29:44 +01:00
28 changed files with 8665 additions and 170 deletions

20
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,20 @@
**This repository's issues are reserved for feature requests, bug reports, and other issues with Pa11y Dashboard itself.**
If you need help using Pa11y Dashboard, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/pa11y).
For a bug report, please use the template below. To keep the backlog clean and actionable, issues may be immediately closed if they do not follow one this template.
---
## Expected behaviour
## Actual behaviour
## Steps to reproduce
## Environment
_Please specify the versions of Pa11y Dashboard, MongoDB, and Node.js that can be sued to reproduce this issue._

View File

@@ -1,19 +1,14 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests.
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Build and lint name: Build and lint
on: on:
push: push:
branches: # Run actions when code is committed to these branches branches:
- master - main
pull_request: pull_request:
branches: # Run actions when a PR is pushed based on one of these branches
- master
jobs: jobs:
checkout_and_test: checkout_and_test:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
strategy: strategy:
matrix: matrix:
include: include:

View File

@@ -805,7 +805,7 @@ function getStandards() {
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 4.5:1.' description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 4.5:1.'
}, },
{ {
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.G145 ', name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.G1451',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 3:1.' description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 3:1.'
}, },
{ {
@@ -1430,11 +1430,11 @@ function getStandards() {
description: 'This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of /{value/}. Recommendation: /{colour recommendations/}.' description: 'This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of /{value/}. Recommendation: /{colour recommendations/}.'
}, },
{ {
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G17 ', name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G17-1',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 7:1.' description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 7:1.'
}, },
{ {
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G18 ', name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G18-1',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 4.5:1.' description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 4.5:1.'
}, },
{ {

View File

@@ -33,8 +33,8 @@ require('./app')(config, (error, app) => {
console.log(kleur.grey('mode: %s'), process.env.NODE_ENV); console.log(kleur.grey('mode: %s'), process.env.NODE_ENV);
console.log(kleur.grey('uri: %s'), app.address); console.log(kleur.grey('uri: %s'), app.address);
app.on('route-error', error => { app.on('route-error', routeError => {
const stack = (error.stack ? error.stack.split('\n') : [error.message]); const stack = (routeError.stack ? routeError.stack.split('\n') : [routeError.message]);
const msg = kleur.red(stack.shift()); const msg = kleur.red(stack.shift());
console.error(''); console.error('');
console.error(msg); console.error(msg);
@@ -43,9 +43,9 @@ require('./app')(config, (error, app) => {
// Start the webservice if required // Start the webservice if required
if (typeof config.webservice === 'object') { if (typeof config.webservice === 'object') {
require('pa11y-webservice')(config.webservice, (error, webservice) => { require('pa11y-webservice')(config.webservice, (webserviceError, webservice) => {
if (error) { if (webserviceError) {
console.error(error.stack); console.error(webserviceError.stack);
process.exit(1); process.exit(1);
} }

8438
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,7 @@
"cheerio": "^1.0.0-rc.10", "cheerio": "^1.0.0-rc.10",
"eslint": "^7.27.0", "eslint": "^7.27.0",
"less": "^3.11.1", "less": "^3.11.1",
"mocha": "^8.4.0", "mocha": "^10.2.0",
"pa11y-lint-config": "^2.0.0", "pa11y-lint-config": "^2.0.0",
"proclaim": "^3.6.0", "proclaim": "^3.6.0",
"request": "^2.88.2", "request": "^2.88.2",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -43,9 +43,9 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="col-md-9" role="main"> <main class="col-md-9" role="main">
{{ content }} {{ content }}
</div> </main>
</div> </div>
</div> </div>

View File

@@ -68,10 +68,12 @@
function next() { function next() {
$active $active
.removeClass('active') .removeClass('active')
.attr('aria-selected', false)
.find('> .dropdown-menu > .active') .find('> .dropdown-menu > .active')
.removeClass('active') .removeClass('active')
element.addClass('active') element.addClass('active')
element.attr('aria-selected', true)
if (transition) { if (transition) {
element[0].offsetWidth // reflow for transition element[0].offsetWidth // reflow for transition

View File

@@ -32,7 +32,7 @@ $(function () {
$.support.transition = false $.support.transition = false
var alertHTML = '<div class="alert-message warning fade in">' var alertHTML = '<div class="alert-message warning fade in">'
+ '<a class="close" href="#" data-dismiss="alert">×</a>' + '<a class="close" href="#" data-dismiss="alert" aria-label="Close">×</a>'
+ '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' + '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
+ '</div>' + '</div>'
, alert = $(alertHTML).appendTo('#qunit-fixture').alert() , alert = $(alertHTML).appendTo('#qunit-fixture').alert()

View File

@@ -95,6 +95,11 @@
li a { li a {
text-indent: -20px; text-indent: -20px;
} }
ul.options-menu {
list-style: none;
padding: 5px 0;
margin: 2px 10px 0 0;
}
} }
.dropdown-toggle { .dropdown-toggle {
@@ -262,6 +267,7 @@
} }
/* Task details page*/ /* Task details page*/
.task-header { .task-header {
margin-bottom: 30px; margin-bottom: 30px;
@@ -502,6 +508,10 @@ ul.date-links {
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
.dates-list > li:first-child a {
font-weight: bold;
font-size: 16px;
}
.dates-list a { .dates-list a {
color: #fff; color: #fff;
@@ -709,6 +719,16 @@ ul.date-links {
} }
} }
/* Edit task page */
#skipRules {
position: absolute;
left: -999px;
}
#skipRules:focus {
position: static;
}
/* inline link list */ /* inline link list */
.inline-list { .inline-list {
@@ -760,3 +780,7 @@ ul.date-links {
opacity: 1; opacity: 1;
}; };
} }
section {
margin: 1em 0;
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable complexity */
// This file is part of Pa11y Dashboard. // This file is part of Pa11y Dashboard.
// //
// Pa11y Dashboard is free software: you can redistribute it and/or modify // Pa11y Dashboard is free software: you can redistribute it and/or modify
@@ -30,42 +31,21 @@ function route(app) {
return standard; return standard;
}); });
response.render('new', { response.render('new', {
standards: standards, standards,
isNewTaskPage: true isNewTaskPage: true
}); });
}); });
app.express.post('/new', (request, response) => { app.express.post('/new', (request, response) => {
let parsedActions; const parsedActions = parseActions(request.body.actions);
if (request.body.actions) {
parsedActions = request.body.actions.split(/[\r\n]+/)
.map(action => {
return action.trim();
})
.filter(action => {
return Boolean(action);
});
}
let parsedHeaders; let parsedHeaders;
if (request.body.headers) { if (request.body.headers) {
parsedHeaders = httpHeaders(request.body.headers, true); parsedHeaders = httpHeaders(request.body.headers, true);
} }
const newTask = { const newTask = createNewTask(request, parsedActions, parsedHeaders);
name: request.body.name,
url: request.body.url,
standard: request.body.standard,
ignore: request.body.ignore || [],
timeout: request.body.timeout || undefined,
wait: request.body.wait || undefined,
actions: parsedActions,
username: request.body.username || undefined,
password: request.body.password || undefined,
headers: parsedHeaders,
hideElements: request.body.hideElements || undefined
};
app.webservice.tasks.create(newTask, (error, task) => { app.webservice.tasks.create(newTask, (error, task) => {
if (error) { if (error) {
@@ -84,8 +64,8 @@ function route(app) {
newTask.actions = request.body.actions; newTask.actions = request.body.actions;
newTask.headers = request.body.headers; newTask.headers = request.body.headers;
return response.render('new', { return response.render('new', {
error: error, error,
standards: standards, standards,
task: newTask task: newTask
}); });
} }
@@ -94,3 +74,32 @@ function route(app) {
}); });
} }
function parseActions(actions) {
if (actions) {
return actions.split(/[\r\n]+/)
.map(action => {
return action.trim();
})
.filter(action => {
return Boolean(action);
});
}
}
/* eslint-disable complexity */
function createNewTask(request, actions, headers) {
return {
name: request.body.name,
url: request.body.url,
standard: request.body.standard,
ignore: request.body.ignore || [],
timeout: request.body.timeout || undefined,
wait: request.body.wait || undefined,
actions,
username: request.body.username || undefined,
password: request.body.password || undefined,
headers,
hideElements: request.body.hideElements || undefined
};
}

View File

@@ -29,8 +29,8 @@ function route(app) {
app.webservice app.webservice
.task(request.params.id) .task(request.params.id)
.result(request.params.rid) .result(request.params.rid)
.get({full: true}, (error, result) => { .get({full: true}, (webserviceError, result) => {
if (error) { if (webserviceError) {
return next('route'); return next('route');
} }
response.locals.task = task; response.locals.task = task;

View File

@@ -30,8 +30,8 @@ function route(app) {
app.webservice app.webservice
.task(request.params.id) .task(request.params.id)
.result(request.params.rid) .result(request.params.rid)
.get({full: true}, (error, result) => { .get({full: true}, (webserviceError, result) => {
if (error) { if (webserviceError) {
return next(); return next();
} }
response.render('result', { response.render('result', {

View File

@@ -43,13 +43,15 @@ function route(app) {
task.actions = (task.actions ? task.actions.join('\n') : ''); task.actions = (task.actions ? task.actions.join('\n') : '');
response.render('task/edit', { response.render('task/edit', {
edited: (typeof request.query.edited !== 'undefined'), edited: (typeof request.query.edited !== 'undefined'),
standards: standards, standards,
task: presentTask(task), task: presentTask(task),
isTaskSubPage: true isTaskSubPage: true
}); });
}); });
}); });
/* eslint-disable complexity */
/* eslint-disable max-statements */
app.express.post('/:id/edit', (request, response, next) => { app.express.post('/:id/edit', (request, response, next) => {
app.webservice.task(request.params.id).get({}, (error, task) => { app.webservice.task(request.params.id).get({}, (error, task) => {
if (error) { if (error) {
@@ -57,9 +59,11 @@ function route(app) {
} }
const originalActions = request.body.actions; const originalActions = request.body.actions;
const originalHeaders = request.body.headers; const originalHeaders = request.body.headers;
request.body.ignore = request.body.ignore || []; request.body.ignore = request.body.ignore || [];
request.body.timeout = request.body.timeout || undefined; request.body.timeout = request.body.timeout || undefined;
request.body.wait = request.body.wait || undefined; request.body.wait = request.body.wait || undefined;
if (request.body.actions) { if (request.body.actions) {
request.body.actions = request.body.actions.split(/[\r\n]+/) request.body.actions = request.body.actions.split(/[\r\n]+/)
.map(action => { .map(action => {
@@ -69,15 +73,18 @@ function route(app) {
return Boolean(action); return Boolean(action);
}); });
} }
if (!request.body.actions) { if (!request.body.actions) {
request.body.actions = []; request.body.actions = [];
} }
request.body.username = request.body.username || undefined; request.body.username = request.body.username || undefined;
request.body.password = request.body.password || undefined; request.body.password = request.body.password || undefined;
request.body.hideElements = request.body.hideElements || undefined; request.body.hideElements = request.body.hideElements || undefined;
request.body.headers = httpHeaders(request.body.headers || '', true); request.body.headers = httpHeaders(request.body.headers || '', true);
app.webservice.task(request.params.id).edit(request.body, error => {
if (error) { app.webservice.task(request.params.id).edit(request.body, webserviceError => {
if (webserviceError) {
task.name = request.body.name; task.name = request.body.name;
task.ignore = request.body.ignore; task.ignore = request.body.ignore;
task.timeout = request.body.timeout; task.timeout = request.body.timeout;
@@ -100,9 +107,9 @@ function route(app) {
return standard; return standard;
}); });
return response.render('task/edit', { return response.render('task/edit', {
error: error, webserviceError,
standards: standards, standards,
task: task, task,
isTaskSubPage: true isTaskSubPage: true
}); });
} }

View File

@@ -28,9 +28,9 @@ function route(app) {
if (error) { if (error) {
return next(); return next();
} }
app.webservice.task(request.params.id).results({}, (error, results) => { app.webservice.task(request.params.id).results({}, (webserviceError, results) => {
if (error) { if (webserviceError) {
return next(error); return next(webserviceError);
} }
const presentedResults = presentResultList(results.map(presentResult)); const presentedResults = presentResultList(results.map(presentResult));
response.render('task', { response.render('task', {

View File

@@ -47,19 +47,17 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{> breadcrumb}} {{> breadcrumb}}
<div class="container"> <main class="container" >
{{#if readonly}} {{#if readonly}}
<div class="row readonly-mode"> <div class="row readonly-mode">
{{else}} {{else}}
<div class="row"> <div class="row">
{{/if}} {{/if}}
<section> <div class="section">
<div class="section" role="main"> {{{body}}}
{{{body}}} </div>
</div>
</section>
</div> </div>
</div> </main>
{{> page-footer}} {{> page-footer}}

View File

@@ -78,8 +78,8 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div class="row"> <div class="row">
<div class="col-md-4 col-sm-4 col-xs-6"> <div class="col-md-4 col-sm-4 col-xs-6">
<label class="control-label" for="new-task-wait">Wait (milliseconds)</label> <label class="control-label" for="new-task-wait">Wait (milliseconds)</label>
<input class="form-control" id="new-task-wait" type="text" placeholder="E.g. 3000" name="wait" value="{{task.wait}}"/> <input class="form-control" id="new-task-wait" type="text" placeholder="E.g. 3000" name="wait" value="{{task.wait}}" aria-describedby="int3"/>
<em>(Note: default wait time is 0ms)</em> <em id="int3">(Note: default wait time is 0ms)</em>
</div> </div>
</div> </div>
</div> </div>
@@ -110,7 +110,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div class="row"> <div class="row">
<div class="col-md-4 col-sm-4 col-xs-6"> <div class="col-md-4 col-sm-4 col-xs-6">
<label class="control-label" for="new-task-password">Password</label> <label class="control-label" for="new-task-password">Password</label>
<input class="form-control" id="new-task-password" type="text" name="password" value="{{task.password}}"/> <em>(Note: this will be stored and displayed in plain-text - only suitable for use in a secure environment)</em> <input class="form-control" id="new-task-password" type="text" name="password" value="{{task.password}}" aria-describedby="pwd"/> <span id="pwd"><em>(Note: this will be stored and displayed in plain-text - only suitable for use in a secure environment)</em></span>
</div> </div>
</div> </div>
</div> </div>
@@ -119,8 +119,8 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div class="row"> <div class="row">
<div class="col-md-4 col-sm-4 col-xs-6"> <div class="col-md-4 col-sm-4 col-xs-6">
<label class="control-label" for="new-task-headers">HTTP Headers</label> <label class="control-label" for="new-task-headers">HTTP Headers</label>
<textarea class="form-control" id="new-task-headers" name="headers" placeholder="Cookie: foo=bar">{{task.headers}}</textarea> <textarea class="form-control" id="new-task-headers" name="headers" placeholder="Cookie: foo=bar" aria-describedby="int1">{{task.headers}}</textarea>
<em>(As key/value pairs, separated by newlines/colons)</em> <em id="int1">(As key/value pairs, separated by newlines/colons)</em>
</div> </div>
</div> </div>
</div> </div>
@@ -129,7 +129,8 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div class="row"> <div class="row">
<div class="col-md-4 col-sm-4 col-xs-6"> <div class="col-md-4 col-sm-4 col-xs-6">
<label class="control-label" for="new-task-hide-elements">Hide Elements</label> <label class="control-label" for="new-task-hide-elements">Hide Elements</label>
<input class="form-control" id="new-task-hide-elements" type="text" name="hideElements" value="{{task.hideElements}}" placeholder=".advert, #modal, div[aria-role=presentation]"/> <em>(CSS selector)</em> <input class="form-control" id="new-task-hide-elements" type="text" name="hideElements" value="{{task.hideElements}}" placeholder=".advert, #modal, div[aria-role=presentation]" aria-describedby="int2"/>
<em id="int2">(CSS selector)</em>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -15,16 +15,17 @@ You should have received a copy of the GNU General Public License
along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
}} }}
{{#unless isHomePage}} {{#unless isHomePage}}
<div class="container"> <nav class="container" aria-labelledby="breadcrumb">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<h2 id="breadcrumb" class="sr-only">Breadcrumb Navigation</h2>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><a href="/">Dashboard</a></li> <li><a href="/">Dashboard</a></li>
{{#if isNewTaskPage}} {{#if isNewTaskPage}}
<li class="active">Add URL</li> <li class="active">Add URL</li>
{{/if}} {{/if}}
{{#if isTaskPage}} {{#if isTaskPage}}
<li class="active">{{task.name}}</li> <li class="active">{{task.name}}</li>
{{/if}} {{/if}}
{{#if isTaskSubPage}} {{#if isTaskSubPage}}
<li><a href="{{task.href}}">{{task.name}}</a></li> <li><a href="{{task.href}}">{{task.name}}</a></li>
@@ -36,5 +37,5 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</ol> </ol>
</div> </div>
</div> </div>
</div> </nav>
{{/unless}} {{/unless}}

View File

@@ -18,9 +18,8 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div class="graph-container graph-spacer ruled clearfix"> <div class="graph-container graph-spacer ruled clearfix">
<div class="row"> <div class="row">
<div class="col-md-3 col-sm-4 col-xs-3"> <div class="col-md-3 col-sm-4 col-xs-3">
<span class="btn btn-sm btn-default btn-full-width btn_action_export">Export graph</span> <button class="btn btn-sm btn-default btn-full-width btn_action_export" type="button">Export graph</button>
</div> </div>
<div class="col-md-5 col-sm-6 col-xs-9 pull-right"> <div class="col-md-5 col-sm-6 col-xs-9 pull-right">
<ul class="list-unstyled floated-list series-checkboxes clearfix" data-role="series-checkboxes"></ul> <ul class="list-unstyled floated-list series-checkboxes clearfix" data-role="series-checkboxes"></ul>
</div> </div>
@@ -28,62 +27,63 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div data-role="graph" class="graph"></div> <div data-role="graph" class="graph"></div>
<div class="dashedLegend"> <div class="dashedLegend">
<div class="dashedContainer"> <div class="dashedContainer">
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td class="legendColorBox"> <td class="legendColorBox">
<div class="clearfix legendIcon legendErrors"> <div class="clearfix legendIcon legendErrors">
<div></div> <div></div>
</div> </div>
</td> </td>
<td class="legendLabel">Errors</td> <td class="legendLabel">Errors</td>
</tr> </tr>
<tr> <tr>
<td class="legendColorBox"> <td class="legendColorBox">
<div class="clearfix legendIcon legendWarnings"> <div class="clearfix legendIcon legendWarnings">
<div></div><div></div> <div></div><div></div>
</div> </div>
</td> </td>
<td class="legendLabel">Warnings</td> <td class="legendLabel">Warnings</td>
</tr> </tr>
<tr> <tr>
<td class="legendColorBox"> <td class="legendColorBox">
<div class="clearfix legendIcon legendNotices"> <div class="clearfix legendIcon legendNotices">
<div></div><div></div><div></div> <div></div><div></div><div></div>
</div> </div>
</td> </td>
<td class="legendLabel">Notices</td> <td class="legendLabel">Notices</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<button data-role='zoom-reset' class="btn btn-xs btn-primary pull-right btn-reset hidden">Reset Zoom <i class="glyphicon glyphicon-zoom-out"></i></button> <button data-role='zoom-reset' class="btn btn-xs btn-primary pull-right btn-reset hidden">Reset Zoom <i class="glyphicon glyphicon-zoom-out"></i></button>
</div>
</div>
<div class="col-md-12 hidden"> </div>
<div class="graph-spacer ruled">
<table id="graph-data" class="table graph-table" summary="Accessibility results from Pa11y for this page"> <div class="col-md-12 hidden">
<caption>Pa11y results for this URL</caption> <div class="graph-spacer ruled">
<thead> <table id="graph-data" class="table graph-table" summary="Accessibility results from Pa11y for this page">
<tr> <caption>Pa11y results for this URL</caption>
<th>Date</th> <thead>
<th class="text-center">Errors</th> <tr>
<th class="text-center">Warnings</th> <th>Date</th>
<th class="text-center">Notices</th> <th class="text-center">Errors</th>
</tr> <th class="text-center">Warnings</th>
</thead> <th class="text-center">Notices</th>
<tbody> </tr>
{{#results}} </thead>
<tr data-role="url-stats"> <tbody>
<td data-value="{{date-timestamp date}}" data-role="date">{{date-format date format="DD MMM YYYY"}}</td> {{#results}}
<td class="text-center" data-label="error">{{count.error}}</td> <tr data-role="url-stats">
<td class="text-center" data-label="warning">{{count.warning}}</td> <td data-value="{{date-timestamp date}}" data-role="date">{{date-format date format="DD MMM YYYY"}}</td>
<td class="text-center" data-label="notice">{{count.notice}}</td> <td class="text-center" data-label="error">{{count.error}}</td>
</tr> <td class="text-center" data-label="warning">{{count.warning}}</td>
{{/results}} <td class="text-center" data-label="notice">{{count.notice}}</td>
</tbody> </tr>
</table> {{/results}}
</tbody>
</table>
</div>
</div> </div>
</div> </div>

View File

@@ -32,15 +32,14 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
</div> </div>
</div> </div>
<div class="row date-selector-row"> <div class="row date-selector-row">
<div id="top" class="col-md-12 col-sm-12 clearfix"> <div class="col-md-12 col-sm-12 clearfix">
<div class="well dark-well"> <div class="well dark-well">
<div class="date-selector"> <div class="date-selector">
<div class="btn-group block-level clearfix"> <div class="btn-group block-level clearfix">
<h2 class="h4">
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>&nbsp;&nbsp;{{date-format task.lastResult.date format="DD MMM YYYY"}} <h2 class="h3" id="dates-navigation">Select a date to show stats for: <span class="glyphicon glyphicon-calendar"></span></h2>
</h2>
<h3 class="h5 show-stats" id="dates-navigation">Select a date to show stats for:</h3>
<nav aria-labelledby="dates-navigation"> <nav aria-labelledby="dates-navigation">
<ul class="dates-list"> <ul class="dates-list">
{{#results}} {{#results}}
@@ -56,31 +55,32 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<div class="row"> <div class="row">
<div class="col-md-12 col-sm-12 clearfix"> <div class="col-md-12 col-sm-12 clearfix">
<div class="well"> <div class="well">
<h4 class="crunch-top">View results in browser</h4> <h2 class="crunch-top h3">View results in browser</h2>
<p class="crunch-bottom">Pa11y uses HTML_CodeSniffer to find accessibility issues. <a href="http://squizlabs.github.io/HTML_CodeSniffer/">Use their bookmarklet</a> to view results on the page you are testing.</p> <p class="crunch-bottom">Pa11y uses HTML_CodeSniffer to find accessibility issues. <a href="http://squizlabs.github.io/HTML_CodeSniffer/">Use their bookmarklet</a> to view results on the page you are testing.</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-9"> <section class="col-md-9" id="top">
<ul class="nav nav-tabs category-list" role="tablist"> <h2 id="tabSectionHeading" class="crunch-top">Results</h2>
<li class="category-list__item category-list__item_type_error active" role="presentation"> <ul class="nav nav-tabs category-list" aria-labelledby="tabSectionHeading" role="tablist">
<li class="category-list__item category-list__item_type_error active" aria-selected="true" role="presentation">
<a class="category-list__link" id="errors" href="#errors-list" aria-controls="errors-list" role="tab" data-toggle="tab" data-test="task-errors"> <a class="category-list__link" id="errors" href="#errors-list" aria-controls="errors-list" role="tab" data-toggle="tab" data-test="task-errors">
Errors ( {{mainResult.count.error}} ) Errors ( {{mainResult.count.error}} )
</a> </a>
</li> </li>
<li class="category-list__item category-list__item_type_warning" role="presentation"> <li class="category-list__item category-list__item_type_warning" aria-selected="false" role="presentation">
<a class="category-list__link" id="warnings" href="#warnings-list" aria-controls="warnings-list" role="tab" data-toggle="tab" data-test="task-warnings"> <a class="category-list__link" id="warnings" href="#warnings-list" aria-controls="warnings-list" role="tab" data-toggle="tab" data-test="task-warnings">
Warnings ( {{mainResult.count.warning}} ) Warnings ( {{mainResult.count.warning}} )
</a> </a>
</li> </li>
<li class="category-list__item category-list__item_type_notice" role="presentation"> <li class="category-list__item category-list__item_type_notice" aria-selected="false" role="presentation">
<a class="category-list__link" id="notices" href="#notices-list" aria-controls="notices-list" role="tab" data-toggle="tab" data-test="task-notices"> <a class="category-list__link" id="notices" href="#notices-list" aria-controls="notices-list" role="tab" data-toggle="tab" data-test="task-notices">
Notices ( {{mainResult.count.notice}} ) Notices ( {{mainResult.count.notice}} )
</a> </a>
</li> </li>
<li class="category-list__item category-list__item_type_ignore" role="presentation"> <li class="category-list__item category-list__item_type_ignore" aria-selected="false" role="presentation">
<a class="category-list__link" id="ignore" href="#ignore-list" aria-controls="ignore-list" role="tab" data-toggle="tab"> <a class="category-list__link" id="ignore" href="#ignore-list" aria-controls="ignore-list" role="tab" data-toggle="tab">
Ignored rules ( {{mainResult.ignore.length}} ) Ignored rules ( {{mainResult.ignore.length}} )
</a> </a>
@@ -88,7 +88,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div id="errors-list" role="tabpanel" class="tab-pane tasks-list fade in active"> <div id="errors-list" role="tabpanel" class="tab-pane tasks-list fade in active" aria-labelledby="errors">
{{#if mainResult.count.error}} {{#if mainResult.count.error}}
{{#mainResult.errors}} {{#mainResult.errors}}
<div class="panel panel-default task task_type_error"> <div class="panel panel-default task task_type_error">
@@ -147,14 +147,14 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
{{/mainResult.errors}} {{/mainResult.errors}}
<div class="to-top"> <div class="to-top">
<a class="link" href="#top" data-role="top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a> <a class="link" href="#top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a>
</div> </div>
{{else}} {{else}}
<div class="text">Well done! You have 0 errors. <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div> <div class="text">Well done! You have 0 errors. <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div>
{{/if}} {{/if}}
</div> </div>
<div id="warnings-list" role="tabpanel" class="tab-pane tasks-list fade"> <div id="warnings-list" role="tabpanel" class="tab-pane tasks-list fade" aria-labelledby="warning">
{{#if mainResult.count.warning}} {{#if mainResult.count.warning}}
{{#mainResult.warnings}} {{#mainResult.warnings}}
<div class="panel panel-default task task_type_warning"> <div class="panel panel-default task task_type_warning">
@@ -213,14 +213,14 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
{{/mainResult.warnings}} {{/mainResult.warnings}}
<div class="to-top"> <div class="to-top">
<a class="link" href="#top" data-role="top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a> <a class="link" href="#top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a>
</div> </div>
{{else}} {{else}}
<div class="text">Well done! You have 0 warnings. <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div> <div class="text">Well done! You have 0 warnings. <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div>
{{/if}} {{/if}}
</div> </div>
<div id="notices-list" role="tabpanel" class="tab-pane tasks-list fade"> <div id="notices-list" role="tabpanel" class="tab-pane tasks-list fade" aria-labelledby="notices">
{{#if mainResult.count.notice}} {{#if mainResult.count.notice}}
{{#mainResult.notices}} {{#mainResult.notices}}
<div class="panel panel-default task task_type_notice"> <div class="panel panel-default task task_type_notice">
@@ -279,14 +279,14 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
{{/mainResult.notices}} {{/mainResult.notices}}
<div class="to-top"> <div class="to-top">
<a class="link" href="#top" data-role="top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a> <a class="link" href="#top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a>
</div> </div>
{{else}} {{else}}
<div class="text">Well done! You have 0 notices. <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div> <div class="text">Well done! You have 0 notices. <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span></div>
{{/if}} {{/if}}
</div> </div>
<div id="ignore-list" role="tabpanel" class="tab-pane tasks-list fade"> <div id="ignore-list" role="tabpanel" class="tab-pane tasks-list fade" aria-labelledby="ignore">
{{#if mainResult.ignore.length}} {{#if mainResult.ignore.length}}
{{#mainResult.ignore}} {{#mainResult.ignore}}
<div class="panel panel-default task task_type_ignore"> <div class="panel panel-default task task_type_ignore">
@@ -316,11 +316,11 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
{{/mainResult.ignore}} {{/mainResult.ignore}}
<div class="to-top"> <div class="to-top">
<a class="link" href="#top" data-role="top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a> <a class="link" href="#top"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>Back to top</a>
</div> </div>
{{else}} {{else}}
<div class="text">You have no ignored rules.</div> <div class="text">You have no ignored rules.</div>
{{/if}} {{/if}}
</div> </div>
</div> </div>
</div> </section>

View File

@@ -14,7 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
}} }}
<div class="col-md-12 zfix"> <section class="col-md-12 zfix">
<div class="ruled task-header"> <div class="ruled task-header">
<div class="row clearfix"> <div class="row clearfix">
<div class="col-md-12"> <div class="col-md-12">
@@ -41,4 +41,4 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
</div> </div>
</div> </div>
</div> </section>

View File

@@ -25,7 +25,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
<li class="col-md-4 col-sm-6 task-card add-task"> <li class="col-md-4 col-sm-6 task-card add-task">
<a class="well task-card-link crunch-bottom" data-role="add-task" href="/new" data-test="add-task"> <a class="well task-card-link crunch-bottom" data-role="add-task" href="/new" data-test="add-task">
<p class="h3 crunch">Add new URL</p> <p class="h3 crunch">Add new URL</p>
<p class="supersize-me crunch">+</p> <p class="supersize-me crunch" aria-hidden="true">+</p>
</a> </a>
</li> </li>
{{/unless}} {{/unless}}
@@ -56,8 +56,8 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{#unless ../readonly}} {{#unless ../readonly}}
<div class="btn-group options-button text-right"> <div class="btn-group options-button text-right">
<button type="button" class="btn btn-info btn-xs dropdown-toggle" data-toggle="dropdown"><span class="sr-only">Options</span><span class="glyphicon glyphicon-cog"></span></button> <button type="button" class="btn btn-info btn-xs dropdown-toggle" data-toggle="dropdown"><span class="sr-only">Options</span><span class="glyphicon glyphicon-cog"></span></button>
<nav aria-label="task tools"> <nav class="dropdown-menu pull-right" aria-label="task tools">
<ul class="dropdown-menu pull-right"> <ul class="options-menu">
<li><a href="{{href}}/edit">Edit this task</a></li> <li><a href="{{href}}/edit">Edit this task</a></li>
<li><a href="{{href}}/delete">Delete this task</a></li> <li><a href="{{href}}/delete">Delete this task</a></li>
<li class="divider"></li> <li class="divider"></li>

View File

@@ -22,7 +22,7 @@ module.exports = presentIgnoreRules;
function presentIgnoreRules(ignore) { function presentIgnoreRules(ignore) {
return ignore.map(name => { return ignore.map(name => {
return { return {
name: name, name,
description: rules[name] description: rules[name]
}; };
}); });

View File

@@ -16,7 +16,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
}} }}
{{#content "title"}} {{#content "title"}}
{{task.name}} - {{simplify-url task.url}} ({{task.standard}}) - {{date-format mainResult.date format="DD MMM YYYY"}} Pa11y Dashboard Results - {{task.name}} - {{date-format mainResult.date format="DD MMM YYYY"}}
{{/content}} {{/content}}
{{> result-header}} {{> result-header}}

View File

@@ -22,7 +22,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{#edited}} {{#edited}}
<div class="col-md-12 clearfix" data-test="alert"> <div class="col-md-12 clearfix" data-test="alert">
<div class="alert alert-success"> <div class="alert alert-success">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button> <button aria-hidden="true" data-dismiss="alert" class="close" type="button" aria-label="Close">×</button>
<strong>Success!</strong> <strong>Success!</strong>
<p>Your changes have been saved.</p> <p>Your changes have been saved.</p>
</div> </div>
@@ -146,7 +146,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
</div> </div>
</div> </div>
<p class="control-label"><b>Ignore these rules</b> <a target="_blank" href="https://github.com/pa11y/pa11y/wiki/HTML-CodeSniffer-Rules">(full list of rules here)</a></p> <p class="control-label"><b>Ignore these rules</b> (<a target="_blank" href="https://github.com/pa11y/pa11y/wiki/HTML-CodeSniffer-Rules">full list of rules here</a>) <a href="#submitEditBtn" id="skipRules">Skip list of rules</a></p>
<div class="standards-lists"> <div class="standards-lists">
{{#standards}} {{#standards}}
@@ -166,7 +166,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{/standards}} {{/standards}}
</div> </div>
<button type="submit" class="btn btn-success">Save changes <span class="glyphicon glyphicon-save"></span></button> <button type="submit" id="submitEditBtn" class="btn btn-success">Save changes <span class="glyphicon glyphicon-save"></span></button>
<a href="/{{task.id}}/edit" class="btn btn-primary">Undo <span class="glyphicon glyphicon-refresh"></span></a> <a href="/{{task.id}}/edit" class="btn btn-primary">Undo <span class="glyphicon glyphicon-refresh"></span></a>
</form> </form>

View File

@@ -16,13 +16,13 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
}} }}
{{#content "title"}} {{#content "title"}}
{{task.name}} - {{simplify-url task.url}} ({{task.standard}}) Pa11y Dashboard Results for {{task.name}} - ({{task.standard}})
{{/content}} {{/content}}
{{#added}} {{#added}}
<div class="col-md-12 clearfix" data-test="alert"> <div class="col-md-12 clearfix" data-test="alert">
<div class="alert alert-success"> <div class="alert alert-success">
<button data-dismiss="alert" class="close" type="button">×</button> <button data-dismiss="alert" class="close" type="button" aria-label="Close">×</button>
<strong>Whoop whoop!</strong> <strong>Whoop whoop!</strong>
<p>Your new URL has been added.</p> <p>Your new URL has been added.</p>
</div> </div>
@@ -32,7 +32,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{#running}} {{#running}}
<div class="col-md-12 clearfix" data-test="alert"> <div class="col-md-12 clearfix" data-test="alert">
<div class="alert alert-success"> <div class="alert alert-success">
<button data-dismiss="alert" class="close" type="button">×</button> <button data-dismiss="alert" class="close" type="button" aria-label="Close">×</button>
<strong>New results incoming!</strong> <strong>New results incoming!</strong>
<p> <p>
New results are being generated for this URL in the background. New results are being generated for this URL in the background.
@@ -45,7 +45,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{#ruleIgnored}} {{#ruleIgnored}}
<div class="col-md-12 clearfix" data-test="alert"> <div class="col-md-12 clearfix" data-test="alert">
<div class="alert alert-success"> <div class="alert alert-success">
<button data-dismiss="alert" class="close" type="button">×</button> <button data-dismiss="alert" class="close" type="button" aria-label="Close">×</button>
<strong>Rule ignored!</strong> <strong>Rule ignored!</strong>
<p> <p>
You've ignored an accessibility rule for this URL. You've ignored an accessibility rule for this URL.
@@ -58,7 +58,7 @@ along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
{{#ruleUnignored}} {{#ruleUnignored}}
<div class="col-md-12 clearfix" data-test="alert"> <div class="col-md-12 clearfix" data-test="alert">
<div class="alert alert-success"> <div class="alert alert-success">
<button data-dismiss="alert" class="close" type="button">×</button> <button data-dismiss="alert" class="close" type="button" aria-label="Close">×</button>
<strong>Rule unignored!</strong> <strong>Rule unignored!</strong>
<p> <p>
You've removed an ignored accessibility rule for this URL. You've removed an ignored accessibility rule for this URL.