forked from external-repos/pa11y-dashboard
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0a14a321d2 | ||
![]() |
ae6208d87e | ||
![]() |
6bfb4f72d9 | ||
![]() |
b3a28bb1e8 | ||
![]() |
4bd5613427 | ||
![]() |
17b04daae0 | ||
![]() |
c15cc32542 | ||
![]() |
08a1a9060f | ||
![]() |
1358d0f38d | ||
![]() |
4eb2fba6aa | ||
![]() |
6a1e06a435 | ||
![]() |
5bfc958270 | ||
![]() |
7ce4127908 | ||
![]() |
2a15773e04 | ||
![]() |
aa3f0eb727 | ||
![]() |
aad26d8cd1 | ||
![]() |
fbe6875cf0 | ||
![]() |
c0ee197138 | ||
![]() |
1723472b93 | ||
![]() |
f8f1e8c15d | ||
![]() |
95869aae56 | ||
![]() |
83d8503ef6 | ||
![]() |
1e5e310b4e | ||
![]() |
7e8d6b122b | ||
![]() |
a2e7e1ffc4 | ||
![]() |
feacb2601d | ||
![]() |
358278ad00 | ||
![]() |
a94a9ed465 | ||
![]() |
0918403876 | ||
![]() |
e7b7792f89 | ||
![]() |
46b2fcd3af | ||
![]() |
c298668b76 |
11
.travis.yml
11
.travis.yml
@@ -3,16 +3,11 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
|
||||||
# Run tests in Node.js 0.10 (unsupported)
|
|
||||||
- node_js: '0.10'
|
- node_js: '0.10'
|
||||||
|
|
||||||
# Run tests in Node.js 0.12
|
|
||||||
- node_js: '0.12'
|
- node_js: '0.12'
|
||||||
|
- node_js: '4'
|
||||||
# Allow Node.js 0.10 to fail – it's unsupported
|
- node_js: '5'
|
||||||
allow_failures:
|
- node_js: '6'
|
||||||
- node_js: '0.10'
|
|
||||||
|
|
||||||
# Build only master (and pull-requests)
|
# Build only master (and pull-requests)
|
||||||
branches:
|
branches:
|
||||||
|
185
CHANGELOG.md
Normal file
185
CHANGELOG.md
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 1.12.0 (2016-05-26)
|
||||||
|
|
||||||
|
* Update Node.js version support to 0.10–6.0
|
||||||
|
* Update dependencies
|
||||||
|
* body-parser: added at ~1.15
|
||||||
|
* chalk: ~0.2 to ~1.1
|
||||||
|
* compression: added at ~1.6
|
||||||
|
* express: ~3.4 to ~4.13
|
||||||
|
* express-hbs: ~0.2 to ~1.0
|
||||||
|
* moment: ~2.2 to ~2.13
|
||||||
|
* pa11y-webservice: ~1.10 to ~1.11
|
||||||
|
* pa11y-webservice-client-node: ~1.1 to ~1.2
|
||||||
|
* bower: ~1.2 to ~1.7
|
||||||
|
* cheerio: added at ~0.20
|
||||||
|
* jsdom: removed
|
||||||
|
* request: ~2.27 to ^2
|
||||||
|
* uglify-js: ~2.4 to ~2.6
|
||||||
|
|
||||||
|
## 1.11.0 (2016-05-23)
|
||||||
|
|
||||||
|
* Add the ability to configure task wait times
|
||||||
|
* Allow configuration by environment variables
|
||||||
|
* Update repository references to the new Pa11y organisation
|
||||||
|
* Add a changelog
|
||||||
|
|
||||||
|
## 1.10.0 (2016-05-18)
|
||||||
|
|
||||||
|
* Automatically focus on the filter input box when you select the filter
|
||||||
|
* Make a task URL clickable
|
||||||
|
* Tweak the documentation to make it more usable
|
||||||
|
* Add a resources section to the README
|
||||||
|
|
||||||
|
## 1.9.0 (2016-04-25)
|
||||||
|
|
||||||
|
* Show errors' context and selector on the results page
|
||||||
|
* Add context and selector to CSV output
|
||||||
|
* Fix lint errors
|
||||||
|
* Switch from Grunt to Make
|
||||||
|
* Add a `SIGINT` handler
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice: ~1.6 to ~1.8
|
||||||
|
|
||||||
|
## 1.8.2 (2016-02-10)
|
||||||
|
|
||||||
|
* Update the license in the footer
|
||||||
|
|
||||||
|
## 1.8.1 (2016-02-10)
|
||||||
|
|
||||||
|
* Update repository references to springernature
|
||||||
|
|
||||||
|
## 1.8.0 (2016-02-04)
|
||||||
|
|
||||||
|
* Make the graph more accessible to color-blind users
|
||||||
|
* Fix lint errors
|
||||||
|
|
||||||
|
## 1.7.0 (2016-01-29)
|
||||||
|
|
||||||
|
* Hide the date list from individual result pages
|
||||||
|
* Make the date selector properly keyboard accessible
|
||||||
|
* Change the options button into a more accessible list
|
||||||
|
* Make the errors/warnings/notices lists keyboard accessible
|
||||||
|
|
||||||
|
## 1.6.1 (2016-01-26)
|
||||||
|
|
||||||
|
* Add keyboard access for filters
|
||||||
|
* Fix lint errors
|
||||||
|
|
||||||
|
## 1.6.0 (2015-08-20)
|
||||||
|
|
||||||
|
* Hide all graph data except for errors by default
|
||||||
|
|
||||||
|
## 1.5.0 (2015-07-06)
|
||||||
|
|
||||||
|
* Add the ability to use HTTP basic auth with task URLs
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice: ~1.5 to ~1.6
|
||||||
|
|
||||||
|
## 1.4.0 (2015-07-02)
|
||||||
|
|
||||||
|
* Add the ability to set a per-task timeout
|
||||||
|
|
||||||
|
## 1.3.2 (2015-01-17)
|
||||||
|
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice: ~1.3 to ~1.4
|
||||||
|
|
||||||
|
## 1.3.1 (2014-03-05)
|
||||||
|
|
||||||
|
* Fix the URL filter position when in demo mode
|
||||||
|
|
||||||
|
## 1.3.0 (2014-03-04)
|
||||||
|
|
||||||
|
* Add filtering of tasks on the home page
|
||||||
|
* Add the ability to ignore certain rules
|
||||||
|
* Add the ability to ignore a rule from the result page
|
||||||
|
* Tweak the display of task cards
|
||||||
|
|
||||||
|
## 1.2.3 (2014-01-13)
|
||||||
|
|
||||||
|
* Fix CSV export for the OS X version of Excel
|
||||||
|
|
||||||
|
## 1.2.2 (2014-01-09)
|
||||||
|
|
||||||
|
* Fix spacing issues when the graph is not visible
|
||||||
|
* Add notes on publishing a release
|
||||||
|
|
||||||
|
## 1.2.1 (2014-01-08)
|
||||||
|
|
||||||
|
* Fix dropdown positioning in Internet Explorer 7 and 8
|
||||||
|
|
||||||
|
## 1.2.0 (2013-12-12)
|
||||||
|
|
||||||
|
* Add HTML Codesniffer links on the results page
|
||||||
|
* Display the ignore rules for results on the results page
|
||||||
|
* Link the breadcrumbs on task sub-pages
|
||||||
|
* Fix an issue with saving empty ignore rules
|
||||||
|
* Cache-bust the CSS and JavaScript
|
||||||
|
* Add the ability to edit tasks
|
||||||
|
* Fix lint errors
|
||||||
|
* Tweaks to the display of the graphs
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice: ~1.1 to ~1.2
|
||||||
|
* pa11y-webservice-client-node: ~1.0 to ~1.1
|
||||||
|
|
||||||
|
## 1.1.0 (2013-11-22)
|
||||||
|
|
||||||
|
* Add a functional test suite
|
||||||
|
* Allow the webservice to run automatically
|
||||||
|
* Documentation improvements
|
||||||
|
* Add a Travis config
|
||||||
|
* Fix lint errors
|
||||||
|
|
||||||
|
## 1.0.0 (2013-11-19)
|
||||||
|
|
||||||
|
* Initial stable release
|
||||||
|
* Add the ability to set a site-wide message
|
||||||
|
* Add a demo mode for demo/public-facing sites
|
||||||
|
* Disable search engine indexing by default
|
||||||
|
* Tweak the task header at smaller screen sizes
|
||||||
|
* Make checkboxes on the graph WCAG2AA compliant
|
||||||
|
* Make checkbox inputs and labels WCAG2AA compliant on new URL page
|
||||||
|
* Colour changes to ensure there are no contrast issues
|
||||||
|
* Make the copy more consistent
|
||||||
|
* Update screenshots
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice-client-node: 1.0.0-beta.7 to ~1.0
|
||||||
|
|
||||||
|
## 1.0.0-beta.3 pre-release (2013-11-12)
|
||||||
|
|
||||||
|
* Fix lint errors
|
||||||
|
* Add descriptive labels to tasks
|
||||||
|
* Add a name field to "New URL" form
|
||||||
|
* Add a WCAG 2.0 link to the footer
|
||||||
|
* Tweak the layout at smaller screen sizes
|
||||||
|
* Notify users when there are no ignored rules
|
||||||
|
* Fix the expires headers for front end assets
|
||||||
|
* Move from Make to Grunt
|
||||||
|
* Compress static files
|
||||||
|
* Minify the site JavaScript
|
||||||
|
* Compile LESS files with grunt
|
||||||
|
* Add a watch task to recompile assets on change
|
||||||
|
* Commit compiled front-end code to the repo
|
||||||
|
* Add development instructions
|
||||||
|
* Update screenshots
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice-client-node: 1.0.0-beta.4 to 1.0.0-beta.7
|
||||||
|
|
||||||
|
## 1.0.0-beta.2 pre-release (2013-10-04)
|
||||||
|
|
||||||
|
* Add screenshots to the README
|
||||||
|
* Fix margins
|
||||||
|
* Add bower package management
|
||||||
|
* Stop the graph from appearing if there's only one result
|
||||||
|
* Add the ability to run tasks ad-hoc
|
||||||
|
* Add more useful information to the footer
|
||||||
|
* General copy edits
|
||||||
|
* Update dependencies
|
||||||
|
* pa11y-webservice-client-node: 1.0.0-beta.3 to 1.0.0-beta.4
|
||||||
|
|
||||||
|
## 1.0.0-beta.1 pre-release (2013-09-27)
|
||||||
|
|
||||||
|
* Initial release
|
82
README.md
82
README.md
@@ -3,9 +3,16 @@ pa11y-dashboard
|
|||||||
|
|
||||||
pa11y-dashboard is a web interface to the [pa11y][pa11y] accessibility reporter; allowing you to focus on *fixing* issues rather than hunting them down.
|
pa11y-dashboard is a web interface to the [pa11y][pa11y] accessibility reporter; allowing you to focus on *fixing* issues rather than hunting them down.
|
||||||
|
|
||||||
**Current Version:** *1.9.0*
|
![Version][shield-version]
|
||||||
**Build Status:** [![Build Status][travis-img]][travis]
|
[![Node.js version support][shield-node]][info-node]
|
||||||
**Node Version Support:** *0.10*
|
[![Build status][shield-build]][info-build]
|
||||||
|
[![GPL-3.0 licensed][shield-license]][info-license]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
✨ 🔜 ✨ The Pa11y team is very excited to announce plans for the successor to pa11y-dashboard and pa11y-webservice, codename "Sidekick". Help us define the features that you want to see by visiting the [proposal][sidekick-proposal]. ✨
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
@@ -15,11 +22,25 @@ pa11y-dashboard is a web interface to the [pa11y][pa11y] accessibility reporter;
|
|||||||
Setup
|
Setup
|
||||||
-----
|
-----
|
||||||
|
|
||||||
pa11y-dashboard requires [Node.js][node] 0.10+, [PhantomJS][phantom], and [MongoDB][mongo] to be installed. See the [pa11y][pa11y] and [pa11y-webservice][pa11y-webservice] documentation for more information on these dependencies.
|
pa11y-dashboard requires [Node.js][node] 0.10+ and [PhantomJS][phantom]. See the [pa11y][pa11y] documentation for detailed instructions on how to install these dependencies on your operating system.
|
||||||
|
|
||||||
You'll then need to clone this repo locally and install dependencies with `npm install`.
|
You'll also need to have [MongoDB][mongo] installed and running. See the [MongoDB install guide][mongo-install] for more information on this.
|
||||||
|
|
||||||
Once you have a local clone, you'll need to copy some sample configuration files in order to run the application. From within the repo, run the following commands:
|
You'll then need to clone this repo locally and install dependencies with `npm install`. Now you need to add some configuration before you can run the application. We can do this in two ways:
|
||||||
|
|
||||||
|
### Option 1: Using Environment Variables
|
||||||
|
|
||||||
|
Each configuration can be set with an environment variable rather than a config file. For example to run the application on port `8080` you can use the following:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PORT=8080 node index.js
|
||||||
|
```
|
||||||
|
|
||||||
|
The [available configurations are documented here](#configurations).
|
||||||
|
|
||||||
|
### Option 2: Using Config Files
|
||||||
|
|
||||||
|
You'll need to copy and modify different config files depending on your environment (set with `NODE_ENV`):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp config/development.sample.json config/development.json
|
cp config/development.sample.json config/development.json
|
||||||
@@ -27,17 +48,15 @@ cp config/production.sample.json config/production.json
|
|||||||
cp config/test.sample.json config/test.json
|
cp config/test.sample.json config/test.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Each of these files defines configurations for a different environment. If you're just running the application locally, then you should be OK with just development configurations. The [available configurations are documented here](#configurations).
|
Each of these files defines configurations for a different environment. If you're just running the application locally, then you should be OK with just development and test configurations. The [available configurations are documented here](#configurations).
|
||||||
|
|
||||||
Now that you've got your application configured, you can run in each mode with the following commands:
|
Now that you've got your application configured, make sure you have a MongoDB server running with the `mongod` command in another terminal window. You can run in each mode by changing the `NODE_ENV` environment variable:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
NODE_ENV=production node index.js # Run in production
|
NODE_ENV=development node index.js
|
||||||
NODE_ENV=development node index.js # Run in development
|
|
||||||
NODE_ENV=test node index.js # Run in test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Check the [development instructions](#development) for more information about running locally (and restarting automatically when files change).
|
See [development instructions](#development) for more information about running locally (and restarting automatically when files change).
|
||||||
|
|
||||||
|
|
||||||
Configurations
|
Configurations
|
||||||
@@ -46,19 +65,19 @@ Configurations
|
|||||||
The boot configurations for pa11y-dashboard are as follows. Look at the sample JSON files in the repo for example usage.
|
The boot configurations for pa11y-dashboard are as follows. Look at the sample JSON files in the repo for example usage.
|
||||||
|
|
||||||
### port
|
### port
|
||||||
*(number)* The port to run the application on.
|
*(number)* The port to run the application on. Set via a config file or the `PORT` environment variable.
|
||||||
|
|
||||||
### noindex
|
### noindex
|
||||||
*(boolean)* If set to `true` (default), the dashboard will not be indexed by search engines. Set to `false` to allow indexing.
|
*(boolean)* If set to `true` (default), the dashboard will not be indexed by search engines. Set to `false` to allow indexing. Set via a config file or the `NOINDEX` environment variable.
|
||||||
|
|
||||||
### readonly
|
### readonly
|
||||||
*(boolean)* If set to `true`, users will not be able to add, delete or run URLs (defaults to `false`).
|
*(boolean)* If set to `true`, users will not be able to add, delete or run URLs (defaults to `false`). Set via a config file or the `READONLY` environment variable.
|
||||||
|
|
||||||
### siteMessage
|
### siteMessage
|
||||||
*(string)* A message to display prominently on the site home page. Defaults to `null`.
|
*(string)* A message to display prominently on the site home page. Defaults to `null`.
|
||||||
|
|
||||||
### webservice
|
### webservice
|
||||||
This can either be an object containing [pa11y-webservice configurations][pa11y-webservice-config], or a string which is the base URL of a [pa11y-webservice][pa11y-webservice] instance you are running separately.
|
This can either be an object containing [pa11y-webservice configurations][pa11y-webservice-config], or a string which is the base URL of a [pa11y-webservice][pa11y-webservice] instance you are running separately. If using environment variables, prefix the webservice vars with `WEBSERVICE_`.
|
||||||
|
|
||||||
|
|
||||||
Development
|
Development
|
||||||
@@ -85,25 +104,40 @@ Code with lint errors or failing tests will not be accepted, please use the buil
|
|||||||
To compile the client-side JavaScript and CSS, you'll need the following commands. Compiled code is committed to the repository.
|
To compile the client-side JavaScript and CSS, you'll need the following commands. Compiled code is committed to the repository.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make css # Compile the site CSS from LESS files
|
make less # Compile the site CSS from LESS files
|
||||||
make uglify # Compile and uglify the client-side JavaScript
|
make uglify # Compile and uglify the client-side JavaScript
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Useful Resources
|
||||||
|
-------
|
||||||
|
* [Setting up An Accessibility Dashboard from Scratch with Pa11y on DigitialOcean][resource-una-k]
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
[Copyright 2013 Springer Nature](LICENSE.txt).
|
pa11y-dashboard is licensed under the [GNU General Public License 3.0][info-license].
|
||||||
pa11y-dashboard is licensed under the [GNU General Public License 3.0][gpl].
|
Copyright © 2013–2016, Springer Nature
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[gpl]: http://www.gnu.org/licenses/gpl-3.0.html
|
[gpl]: http://www.gnu.org/licenses/gpl-3.0.html
|
||||||
[mongo]: http://www.mongodb.org/
|
[mongo]: http://www.mongodb.org/
|
||||||
|
[mongo-install]: https://docs.mongodb.org/manual/installation/
|
||||||
[node]: http://nodejs.org/
|
[node]: http://nodejs.org/
|
||||||
[pa11y]: https://github.com/springernature/pa11y
|
[pa11y]: https://github.com/pa11y/pa11y
|
||||||
[pa11y-webservice]: https://github.com/springernature/pa11y-webservice
|
[pa11y-webservice-config]: https://github.com/pa11y/pa11y-webservice#configurations
|
||||||
[pa11y-webservice-config]: https://github.com/springernature/pa11y-webservice#configurations
|
|
||||||
[phantom]: http://phantomjs.org/
|
[phantom]: http://phantomjs.org/
|
||||||
[travis]: https://travis-ci.org/springernature/pa11y-dashboard
|
[resource-una-k]: https://una.im/pa11y-dash/
|
||||||
[travis-img]: https://travis-ci.org/springernature/pa11y-dashboard.png?branch=master
|
[sidekick-proposal]: https://github.com/pa11y/sidekick/blob/master/PROPOSAL.md
|
||||||
|
[travis]: https://travis-ci.org/pa11y/pa11y-dashboard
|
||||||
|
[travis-img]: https://travis-ci.org/pa11y/pa11y-dashboard.png?branch=master
|
||||||
|
|
||||||
|
[info-license]: LICENSE
|
||||||
|
[info-node]: package.json
|
||||||
|
[info-build]: https://travis-ci.org/pa11y/pa11y-dashboard
|
||||||
|
[shield-license]: https://img.shields.io/badge/license-GPL%203.0-blue.svg
|
||||||
|
[shield-node]: https://img.shields.io/badge/node.js%20support-0.10–6-brightgreen.svg
|
||||||
|
[shield-version]: https://img.shields.io/badge/version-1.12.0-blue.svg
|
||||||
|
[shield-build]: https://img.shields.io/travis/pa11y/pa11y-dashboard/master.svg
|
||||||
|
27
app.js
27
app.js
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var bodyParser = require('body-parser');
|
||||||
|
var compression = require('compression');
|
||||||
var createClient = require('pa11y-webservice-client-node');
|
var createClient = require('pa11y-webservice-client-node');
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
@@ -40,7 +42,7 @@ function initApp(config, callback) {
|
|||||||
app.webservice = createClient(webserviceUrl);
|
app.webservice = createClient(webserviceUrl);
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
app.express.use(express.compress());
|
app.express.use(compression());
|
||||||
|
|
||||||
// Public files
|
// Public files
|
||||||
app.express.use(express.static(__dirname + '/public', {
|
app.express.use(express.static(__dirname + '/public', {
|
||||||
@@ -49,26 +51,28 @@ function initApp(config, callback) {
|
|||||||
|
|
||||||
// General express config
|
// General express config
|
||||||
app.express.disable('x-powered-by');
|
app.express.disable('x-powered-by');
|
||||||
app.express.use(express.bodyParser());
|
app.express.use(bodyParser.urlencoded({
|
||||||
|
extended: true
|
||||||
|
}));
|
||||||
|
|
||||||
// View engine
|
// View engine
|
||||||
app.express.set('views', __dirname + '/view');
|
app.express.engine('html', hbs.express4({
|
||||||
app.express.engine('html', hbs.express3({
|
|
||||||
extname: '.html',
|
extname: '.html',
|
||||||
contentHelperName: 'content',
|
contentHelperName: 'content',
|
||||||
layoutsDir: __dirname + '/view/layout',
|
layoutsDir: __dirname + '/view/layout',
|
||||||
partialsDir: __dirname + '/view/partial',
|
partialsDir: __dirname + '/view/partial',
|
||||||
defaultLayout: __dirname + '/view/layout/default'
|
defaultLayout: __dirname + '/view/layout/default'
|
||||||
}));
|
}));
|
||||||
|
app.express.set('views', __dirname + '/view');
|
||||||
app.express.set('view engine', 'html');
|
app.express.set('view engine', 'html');
|
||||||
|
|
||||||
// View helpers
|
// View helpers
|
||||||
require('./view/helper/date')(hbs.registerHelper);
|
require('./view/helper/date')(hbs);
|
||||||
require('./view/helper/string')(hbs.registerHelper);
|
require('./view/helper/string')(hbs);
|
||||||
require('./view/helper/url')(hbs.registerHelper);
|
require('./view/helper/url')(hbs);
|
||||||
|
|
||||||
// Populate view locals
|
// Populate view locals
|
||||||
app.express.locals({
|
app.express.locals = {
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
year: (new Date()).getFullYear(),
|
year: (new Date()).getFullYear(),
|
||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
@@ -76,12 +80,13 @@ function initApp(config, callback) {
|
|||||||
bugtracker: pkg.bugs,
|
bugtracker: pkg.bugs,
|
||||||
noindex: config.noindex,
|
noindex: config.noindex,
|
||||||
readonly: config.readonly,
|
readonly: config.readonly,
|
||||||
siteMessage: config.siteMessage
|
siteMessage: config.siteMessage,
|
||||||
});
|
settings: {}
|
||||||
|
};
|
||||||
|
|
||||||
app.express.use(function(req, res, next) {
|
app.express.use(function(req, res, next) {
|
||||||
res.locals.isHomePage = (req.path === '/');
|
res.locals.isHomePage = (req.path === '/');
|
||||||
res.locals.host = req.host;
|
res.locals.host = req.hostname;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
41
config.js
Normal file
41
config.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// This file is part of pa11y-dashboard.
|
||||||
|
//
|
||||||
|
// pa11y-dashboard is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// pa11y-dashboard is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with pa11y-dashboard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var jsonPath = './config/' + (process.env.NODE_ENV || 'development') + '.json';
|
||||||
|
|
||||||
|
if (fs.existsSync(jsonPath)) {
|
||||||
|
module.exports = require(jsonPath);
|
||||||
|
} else {
|
||||||
|
module.exports = {
|
||||||
|
port: Number(env('PORT', '4000')),
|
||||||
|
noindex: env('NOINDEX', 'true') === 'true',
|
||||||
|
readonly: env('READONLY', 'false') === 'true',
|
||||||
|
|
||||||
|
webservice: env('WEBSERVICE_URL', {
|
||||||
|
database: env('WEBSERVICE_DATABASE', 'mongodb://localhost/pa11y-webservice'),
|
||||||
|
host: env('WEBSERVICE_HOST', '0.0.0.0'),
|
||||||
|
port: Number(env('WEBSERVICE_PORT', '3000')),
|
||||||
|
cron: env('WEBSERVICE_CRON', false)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function env(name, defaultValue) {
|
||||||
|
var value = process.env[name];
|
||||||
|
return typeof value === 'string' ? value : defaultValue;
|
||||||
|
}
|
2
index.js
2
index.js
@@ -16,7 +16,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var chalk = require('chalk');
|
var chalk = require('chalk');
|
||||||
var config = require('./config/' + (process.env.NODE_ENV || 'development') + '.json');
|
var config = require('./config');
|
||||||
|
|
||||||
process.on('SIGINT', function() {
|
process.on('SIGINT', function() {
|
||||||
console.log('\nGracefully shutting down from SIGINT (Ctrl-C)');
|
console.log('\nGracefully shutting down from SIGINT (Ctrl-C)');
|
||||||
|
34
package.json
34
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pa11y-dashboard",
|
"name": "pa11y-dashboard",
|
||||||
"version": "1.9.0",
|
"version": "1.12.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|
||||||
"description": "pa11y-dashboard is a visual web interface to the pa11y accessibility reporter",
|
"description": "pa11y-dashboard is a visual web interface to the pa11y accessibility reporter",
|
||||||
@@ -12,33 +12,35 @@
|
|||||||
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/springernature/pa11y-dashboard.git"
|
"url": "https://github.com/pa11y/pa11y-dashboard.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/springernature/pa11y-dashboard",
|
"homepage": "https://github.com/pa11y/pa11y-dashboard",
|
||||||
"bugs": "https://github.com/springernature/pa11y-dashboard/issues",
|
"bugs": "https://github.com/pa11y/pa11y-dashboard/issues",
|
||||||
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "~0.2",
|
"body-parser": "~1.15",
|
||||||
"express": "~3.4",
|
"chalk": "~1.1",
|
||||||
"express-hbs": "~0.2",
|
"compression": "~1.6",
|
||||||
"moment": "~2.2",
|
"express": "~4.13",
|
||||||
"pa11y-webservice": "~1.8",
|
"express-hbs": "~1.0",
|
||||||
"pa11y-webservice-client-node": "~1.1",
|
"moment": "~2.13",
|
||||||
"underscore": "~1.5"
|
"pa11y-webservice": "~1.11",
|
||||||
|
"pa11y-webservice-client-node": "~1.2",
|
||||||
|
"underscore": "~1.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bower": "~1.2",
|
"bower": "~1.7",
|
||||||
|
"cheerio": "~0.20",
|
||||||
"jscs": "^2",
|
"jscs": "^2",
|
||||||
"jsdom": "^3",
|
|
||||||
"jshint": "^2",
|
"jshint": "^2",
|
||||||
"less": "~1.5",
|
"less": "~2.7",
|
||||||
"mocha": "^2",
|
"mocha": "^2",
|
||||||
"proclaim": "^3",
|
"proclaim": "^3",
|
||||||
"request": "~2.27",
|
"request": "^2",
|
||||||
"uglify-js": "~2.4"
|
"uglify-js": "~2.6"
|
||||||
},
|
},
|
||||||
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
2
public/css/site.min.css
vendored
2
public/css/site.min.css
vendored
File diff suppressed because one or more lines are too long
12
public/js/site.min.js
vendored
12
public/js/site.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -42,6 +42,7 @@ function route(app) {
|
|||||||
standard: req.body.standard,
|
standard: req.body.standard,
|
||||||
ignore: req.body.ignore || [],
|
ignore: req.body.ignore || [],
|
||||||
timeout: req.body.timeout,
|
timeout: req.body.timeout,
|
||||||
|
wait: req.body.wait,
|
||||||
username: req.body.username,
|
username: req.body.username,
|
||||||
password: req.body.password
|
password: req.body.password
|
||||||
};
|
};
|
||||||
|
@@ -60,6 +60,7 @@ function route(app) {
|
|||||||
task.name = req.body.name;
|
task.name = req.body.name;
|
||||||
task.ignore = req.body.ignore;
|
task.ignore = req.body.ignore;
|
||||||
task.timeout = req.body.timeout;
|
task.timeout = req.body.timeout;
|
||||||
|
task.wait = req.body.wait;
|
||||||
task.username = req.body.username;
|
task.username = req.body.username;
|
||||||
task.password = req.body.password;
|
task.password = req.body.password;
|
||||||
var standards = getStandards().map(function(standard) {
|
var standards = getStandards().map(function(standard) {
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var jsdom = require('jsdom');
|
var cheerio = require('cheerio');
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
|
|
||||||
module.exports = createNavigator;
|
module.exports = createNavigator;
|
||||||
@@ -29,13 +29,12 @@ function createNavigator(baseUrl, store) {
|
|||||||
store.request = null;
|
store.request = null;
|
||||||
store.response = null;
|
store.response = null;
|
||||||
store.status = null;
|
store.status = null;
|
||||||
store.window = null;
|
|
||||||
|
|
||||||
request({
|
request({
|
||||||
url: baseUrl + opts.endpoint,
|
url: baseUrl + opts.endpoint,
|
||||||
method: opts.method || 'GET',
|
method: opts.method || 'GET',
|
||||||
body: opts.body,
|
form: opts.form,
|
||||||
json: true,
|
json: opts.json || false,
|
||||||
qs: opts.query,
|
qs: opts.query,
|
||||||
followAllRedirects: true
|
followAllRedirects: true
|
||||||
}, function(err, res, body) {
|
}, function(err, res, body) {
|
||||||
@@ -46,19 +45,11 @@ function createNavigator(baseUrl, store) {
|
|||||||
store.status = res.statusCode;
|
store.status = res.statusCode;
|
||||||
|
|
||||||
if (opts.nonDom) {
|
if (opts.nonDom) {
|
||||||
store.window = null;
|
|
||||||
store.dom = null;
|
store.dom = null;
|
||||||
callback();
|
|
||||||
} else {
|
} else {
|
||||||
jsdom.env(
|
store.dom = cheerio.load(store.body);
|
||||||
store.body,
|
}
|
||||||
function(err, window) {
|
|
||||||
store.window = window;
|
|
||||||
store.dom = window.document;
|
|
||||||
callback();
|
callback();
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
var assert = require('proclaim');
|
var assert = require('proclaim');
|
||||||
|
|
||||||
describe('GET /', function() {
|
describe.only('GET /', function() {
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
var req = {
|
var req = {
|
||||||
@@ -32,61 +32,61 @@ describe('GET /', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display an "Add new URL" button', function() {
|
it('should display an "Add new URL" button', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=add-task]');
|
var elem = this.last.dom('[data-test=add-task]');
|
||||||
assert.strictEqual(elem.length, 1);
|
assert.strictEqual(elem.length, 1);
|
||||||
assert.strictEqual(elem[0].getAttribute('href'), '/new');
|
assert.strictEqual(elem.eq(0).attr('href'), '/new');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display all of the expected tasks', function() {
|
it('should display all of the expected tasks', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.strictEqual(tasks.length, 3);
|
assert.strictEqual(tasks.length, 3);
|
||||||
assert.match(tasks[0].textContent, /npg home\s+\(wcag2aa\)/i);
|
assert.match(tasks.eq(0).text(), /npg home\s+\(wcag2aa\)/i);
|
||||||
assert.match(tasks[1].textContent, /npg home\s+\(wcag2aaa\)/i);
|
assert.match(tasks.eq(1).text(), /npg home\s+\(wcag2aaa\)/i);
|
||||||
assert.match(tasks[2].textContent, /nature news\s+\(section508\)/i);
|
assert.match(tasks.eq(2).text(), /nature news\s+\(section508\)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have links to each task', function() {
|
it('should have links to each task', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.strictEqual(tasks[0].querySelectorAll('[href="/abc000000000000000000001"]').length, 1);
|
assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001"]').length, 1);
|
||||||
assert.strictEqual(tasks[1].querySelectorAll('[href="/abc000000000000000000002"]').length, 1);
|
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002"]').length, 1);
|
||||||
assert.strictEqual(tasks[2].querySelectorAll('[href="/abc000000000000000000003"]').length, 1);
|
assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display an "Edit" button for each task', function() {
|
it('should display an "Edit" button for each task', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.strictEqual(tasks[0].querySelectorAll('[href="/abc000000000000000000001/edit"]').length, 1);
|
assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001/edit"]').length, 1);
|
||||||
assert.strictEqual(tasks[1].querySelectorAll('[href="/abc000000000000000000002/edit"]').length, 1);
|
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/edit"]').length, 1);
|
||||||
assert.strictEqual(tasks[2].querySelectorAll('[href="/abc000000000000000000003/edit"]').length, 1);
|
assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/edit"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Delete" button for each task', function() {
|
it('should display a "Delete" button for each task', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.strictEqual(tasks[0].querySelectorAll('[href="/abc000000000000000000001/delete"]').length, 1);
|
assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001/delete"]').length, 1);
|
||||||
assert.strictEqual(tasks[1].querySelectorAll('[href="/abc000000000000000000002/delete"]').length, 1);
|
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/delete"]').length, 1);
|
||||||
assert.strictEqual(tasks[2].querySelectorAll('[href="/abc000000000000000000003/delete"]').length, 1);
|
assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/delete"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Run" button for each task', function() {
|
it('should display a "Run" button for each task', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.strictEqual(tasks[0].querySelectorAll('[href="/abc000000000000000000001/run"]').length, 1);
|
assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001/run"]').length, 1);
|
||||||
assert.strictEqual(tasks[1].querySelectorAll('[href="/abc000000000000000000002/run"]').length, 1);
|
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/run"]').length, 1);
|
||||||
assert.strictEqual(tasks[2].querySelectorAll('[href="/abc000000000000000000003/run"]').length, 1);
|
assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/run"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the task result counts if the task has been run', function() {
|
it('should display the task result counts if the task has been run', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.match(tasks[0].textContent, /1\s*errors/i);
|
assert.match(tasks.eq(0).text(), /1\s*errors/i);
|
||||||
assert.match(tasks[0].textContent, /2\s*warnings/i);
|
assert.match(tasks.eq(0).text(), /2\s*warnings/i);
|
||||||
assert.match(tasks[0].textContent, /3\s*notices/i);
|
assert.match(tasks.eq(0).text(), /3\s*notices/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a message indicating that there are no results if the task has not been run', function() {
|
it('should display a message indicating that there are no results if the task has not been run', function() {
|
||||||
var tasks = this.last.dom.querySelectorAll('[data-test=task]');
|
var tasks = this.last.dom('[data-test=task]');
|
||||||
assert.match(tasks[2].textContent, /no results/i);
|
assert.match(tasks.eq(2).text(), /no results/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not display an alert message', function() {
|
it('should not display an alert message', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[data-test=alert]').length, 0);
|
assert.strictEqual(this.last.dom('[data-test=alert]').length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -32,58 +32,65 @@ describe('GET /new', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not display an error message', function() {
|
it('should not display an error message', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[data-test=error]').length, 0);
|
assert.strictEqual(this.last.dom('[data-test=error]').length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have an "Add new URL" form', function() {
|
it('should have an "Add new URL" form', function() {
|
||||||
var form = this.last.dom.querySelectorAll('[data-test=new-url-form]')[0];
|
var form = this.last.dom('[data-test=new-url-form]').eq(0);
|
||||||
assert.isDefined(form);
|
assert.isDefined(form);
|
||||||
assert.strictEqual(form.getAttribute('action'), '/new');
|
assert.strictEqual(form.attr('action'), '/new');
|
||||||
assert.strictEqual(form.getAttribute('method'), 'post');
|
assert.strictEqual(form.attr('method'), 'post');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('"Add New URL" form', function() {
|
describe('"Add New URL" form', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.form = this.last.dom.querySelectorAll('[data-test=new-url-form]')[0];
|
this.form = this.last.dom('[data-test=new-url-form]').eq(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "name" field', function() {
|
it('should have a "name" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=name]')[0];
|
var field = this.form.find('input[name=name]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'text');
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
assert.strictEqual(field.getAttribute('value'), '');
|
assert.strictEqual(field.attr('value'), '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "url" field', function() {
|
it('should have a "url" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=url]')[0];
|
var field = this.form.find('input[name=url]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'url');
|
assert.strictEqual(field.attr('type'), 'url');
|
||||||
assert.strictEqual(field.getAttribute('value'), '');
|
assert.strictEqual(field.attr('value'), '');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a "wait" field', function() {
|
||||||
|
var field = this.form.find('input[name=wait]').eq(0);
|
||||||
|
assert.isDefined(field);
|
||||||
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
|
assert.strictEqual(field.attr('value'), '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "username" field', function() {
|
it('should have a "username" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=username]')[0];
|
var field = this.form.find('input[name=username]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'text');
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
assert.strictEqual(field.getAttribute('value'), '');
|
assert.strictEqual(field.attr('value'), '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "password" field', function() {
|
it('should have a "password" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=password]')[0];
|
var field = this.form.find('input[name=password]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'text');
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
assert.strictEqual(field.getAttribute('value'), '');
|
assert.strictEqual(field.attr('value'), '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "standard" field', function() {
|
it('should have a "standard" field', function() {
|
||||||
var field = this.form.querySelectorAll('select[name=standard]')[0];
|
var field = this.form.find('select[name=standard]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.querySelectorAll('option').length, 4);
|
assert.strictEqual(field.find('option').length, 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "ignore" fields', function() {
|
it('should have "ignore" fields', function() {
|
||||||
var fields = this.form.querySelectorAll('input[name="ignore[]"]');
|
var fields = this.form.find('input[name="ignore[]"]');
|
||||||
assert.isDefined(fields);
|
assert.isDefined(fields);
|
||||||
assert.notStrictEqual(fields.length, 0);
|
assert.notStrictEqual(fields.length, 0);
|
||||||
});
|
});
|
||||||
@@ -100,7 +107,7 @@ describe('POST /new', function() {
|
|||||||
var req = {
|
var req = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
endpoint: '/new',
|
endpoint: '/new',
|
||||||
body: {
|
form: {
|
||||||
name: '',
|
name: '',
|
||||||
url: ''
|
url: ''
|
||||||
}
|
}
|
||||||
@@ -113,7 +120,7 @@ describe('POST /new', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display an error message', function() {
|
it('should display an error message', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[data-test=error]').length, 1);
|
assert.strictEqual(this.last.dom('[data-test=error]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -124,7 +131,7 @@ describe('POST /new', function() {
|
|||||||
var req = {
|
var req = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
endpoint: '/new',
|
endpoint: '/new',
|
||||||
body: {
|
form: {
|
||||||
name: 'Example',
|
name: 'Example',
|
||||||
url: 'http://example.com/',
|
url: 'http://example.com/',
|
||||||
standard: 'WCAG2AA'
|
standard: 'WCAG2AA'
|
||||||
@@ -149,11 +156,11 @@ describe('POST /new', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not display an error message', function() {
|
it('should not display an error message', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[data-test=error]').length, 0);
|
assert.strictEqual(this.last.dom('[data-test=error]').length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a success message', function() {
|
it('should display a success message', function() {
|
||||||
var alert = this.last.dom.querySelectorAll('[data-test=alert]')[0];
|
var alert = this.last.dom('[data-test=alert]').eq(0);
|
||||||
assert.isDefined(alert);
|
assert.isDefined(alert);
|
||||||
assert.match(alert.textContent, /url has been added/i);
|
assert.match(alert.textContent, /url has been added/i);
|
||||||
});
|
});
|
||||||
|
@@ -44,7 +44,8 @@ describe('GET /<task-id>/<result-id>.json', function() {
|
|||||||
var req = {
|
var req = {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
endpoint: '/abc000000000000000000001/def000000000000000000001.json',
|
endpoint: '/abc000000000000000000001/def000000000000000000001.json',
|
||||||
nonDom: true
|
nonDom: true,
|
||||||
|
json: true
|
||||||
};
|
};
|
||||||
this.navigate(req, done);
|
this.navigate(req, done);
|
||||||
});
|
});
|
||||||
|
@@ -32,37 +32,37 @@ describe('GET /<task-id>/<result-id>', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Download CSV" button', function() {
|
it('should display a "Download CSV" button', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=download-csv]');
|
var elem = this.last.dom('[data-test=download-csv]');
|
||||||
assert.strictEqual(elem.length, 1);
|
assert.strictEqual(elem.length, 1);
|
||||||
assert.strictEqual(elem[0].getAttribute('href'), '/abc000000000000000000001/def000000000000000000001.csv');
|
assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.csv');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Download JSON" button', function() {
|
it('should display a "Download JSON" button', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=download-json]');
|
var elem = this.last.dom('[data-test=download-json]');
|
||||||
assert.strictEqual(elem.length, 1);
|
assert.strictEqual(elem.length, 1);
|
||||||
assert.strictEqual(elem[0].getAttribute('href'), '/abc000000000000000000001/def000000000000000000001.json');
|
assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a link back to the task', function() {
|
it('should display a link back to the task', function() {
|
||||||
assert.isDefined(this.last.dom.querySelectorAll('[href="/abc000000000000000000001"]')[0]);
|
assert.isDefined(this.last.dom('[href="/abc000000000000000000001"]').eq(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display errors', function() {
|
it('should display errors', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=task-errors]')[0];
|
var elem = this.last.dom('[data-test=task-errors]').eq(0);
|
||||||
assert.isDefined(elem);
|
assert.isDefined(elem);
|
||||||
assert.match(elem.textContent, /errors \( 1 \)/i);
|
assert.match(elem.text(), /errors \( 1 \)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display warnings', function() {
|
it('should display warnings', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=task-warnings]')[0];
|
var elem = this.last.dom('[data-test=task-warnings]').eq(0);
|
||||||
assert.isDefined(elem);
|
assert.isDefined(elem);
|
||||||
assert.match(elem.textContent, /warnings \( 2 \)/i);
|
assert.match(elem.text(), /warnings \( 2 \)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display notices', function() {
|
it('should display notices', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=task-notices]')[0];
|
var elem = this.last.dom('[data-test=task-notices]').eq(0);
|
||||||
assert.isDefined(elem);
|
assert.isDefined(elem);
|
||||||
assert.match(elem.textContent, /notices \( 3 \)/i);
|
assert.match(elem.text(), /notices \( 3 \)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -32,14 +32,14 @@ describe('GET /<task-id>/delete', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "Delete URL" form', function() {
|
it('should have a "Delete URL" form', function() {
|
||||||
var form = this.last.dom.querySelectorAll('[data-test=delete-url-form]')[0];
|
var form = this.last.dom('[data-test=delete-url-form]').eq(0);
|
||||||
assert.isDefined(form);
|
assert.isDefined(form);
|
||||||
assert.strictEqual(form.getAttribute('action'), '/abc000000000000000000001/delete');
|
assert.strictEqual(form.attr('action'), '/abc000000000000000000001/delete');
|
||||||
assert.strictEqual(form.getAttribute('method'), 'post');
|
assert.strictEqual(form.attr('method'), 'post');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a link back to the task page', function() {
|
it('should display a link back to the task page', function() {
|
||||||
assert.greaterThan(this.last.dom.querySelectorAll('[href="/abc000000000000000000001"]').length, 0);
|
assert.greaterThan(this.last.dom('[href="/abc000000000000000000001"]').length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -70,9 +70,9 @@ describe('POST /<task-id>/delete', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display a success message', function() {
|
it('should display a success message', function() {
|
||||||
var alert = this.last.dom.querySelectorAll('[data-test=alert]')[0];
|
var alert = this.last.dom('[data-test=alert]').eq(0);
|
||||||
assert.isDefined(alert);
|
assert.isDefined(alert);
|
||||||
assert.match(alert.textContent, /been deleted/i);
|
assert.match(alert.text(), /been deleted/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -32,59 +32,66 @@ describe('GET /<task-id>/edit', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have an "Edit URL" form', function() {
|
it('should have an "Edit URL" form', function() {
|
||||||
var form = this.last.dom.querySelectorAll('[data-test=edit-url-form]')[0];
|
var form = this.last.dom('[data-test=edit-url-form]').eq(0);
|
||||||
assert.isDefined(form);
|
assert.isDefined(form);
|
||||||
assert.strictEqual(form.getAttribute('action'), '/abc000000000000000000001/edit');
|
assert.strictEqual(form.attr('action'), '/abc000000000000000000001/edit');
|
||||||
assert.strictEqual(form.getAttribute('method'), 'post');
|
assert.strictEqual(form.attr('method'), 'post');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a link back to the task page', function() {
|
it('should display a link back to the task page', function() {
|
||||||
assert.greaterThan(this.last.dom.querySelectorAll('[href="/abc000000000000000000001"]').length, 0);
|
assert.greaterThan(this.last.dom('[href="/abc000000000000000000001"]').length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('"Edit URL" form', function() {
|
describe('"Edit URL" form', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.form = this.last.dom.querySelectorAll('[data-test=edit-url-form]')[0];
|
this.form = this.last.dom('[data-test=edit-url-form]').eq(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "name" field', function() {
|
it('should have a "name" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=name]')[0];
|
var field = this.form.find('input[name=name]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'text');
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
assert.strictEqual(field.getAttribute('value'), 'NPG Home');
|
assert.strictEqual(field.attr('value'), 'NPG Home');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a disabled "url" field', function() {
|
it('should have a disabled "url" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=url]')[0];
|
var field = this.form.find('input[name=url]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'url');
|
assert.strictEqual(field.attr('type'), 'url');
|
||||||
assert.strictEqual(field.getAttribute('value'), 'nature.com');
|
assert.strictEqual(field.attr('value'), 'nature.com');
|
||||||
assert.isDefined(field.getAttribute('disabled'));
|
assert.isDefined(field.attr('disabled'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a "wait" field', function() {
|
||||||
|
var field = this.form.find('input[name=wait]').eq(0);
|
||||||
|
assert.isDefined(field);
|
||||||
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
|
assert.strictEqual(field.attr('value'), '0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a disabled "standard" field', function() {
|
it('should have a disabled "standard" field', function() {
|
||||||
var field = this.form.querySelectorAll('select[name=standard]')[0];
|
var field = this.form.find('select[name=standard]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.isDefined(field.getAttribute('disabled'));
|
assert.isDefined(field.attr('disabled'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "username" field', function() {
|
it('should have a "username" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=username]')[0];
|
var field = this.form.find('input[name=username]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'text');
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
assert.strictEqual(field.getAttribute('value'), 'user');
|
assert.strictEqual(field.attr('value'), 'user');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "password" field', function() {
|
it('should have a "password" field', function() {
|
||||||
var field = this.form.querySelectorAll('input[name=password]')[0];
|
var field = this.form.find('input[name=password]').eq(0);
|
||||||
assert.isDefined(field);
|
assert.isDefined(field);
|
||||||
assert.strictEqual(field.getAttribute('type'), 'text');
|
assert.strictEqual(field.attr('type'), 'text');
|
||||||
assert.strictEqual(field.getAttribute('value'), 'access');
|
assert.strictEqual(field.attr('value'), 'access');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "ignore" fields', function() {
|
it('should have "ignore" fields', function() {
|
||||||
var fields = this.form.querySelectorAll('input[name="ignore[]"]');
|
var fields = this.form.find('input[name="ignore[]"]');
|
||||||
assert.isDefined(fields);
|
assert.isDefined(fields);
|
||||||
assert.notStrictEqual(fields.length, 0);
|
assert.notStrictEqual(fields.length, 0);
|
||||||
});
|
});
|
||||||
@@ -99,7 +106,7 @@ describe('POST /<task-id>/edit', function() {
|
|||||||
var req = {
|
var req = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
endpoint: '/abc000000000000000000001/edit',
|
endpoint: '/abc000000000000000000001/edit',
|
||||||
body: {
|
form: {
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
username: 'newuser',
|
username: 'newuser',
|
||||||
password: 'secure',
|
password: 'secure',
|
||||||
@@ -124,9 +131,9 @@ describe('POST /<task-id>/edit', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display a success message', function() {
|
it('should display a success message', function() {
|
||||||
var alert = this.last.dom.querySelectorAll('[data-test=alert]')[0];
|
var alert = this.last.dom('[data-test=alert]').eq(0);
|
||||||
assert.isDefined(alert);
|
assert.isDefined(alert);
|
||||||
assert.match(alert.textContent, /been saved/i);
|
assert.match(alert.text(), /been saved/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -34,46 +34,46 @@ describe('GET /<task-id>', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display an "Edit" button', function() {
|
it('should display an "Edit" button', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/edit"]').length, 1);
|
assert.strictEqual(this.last.dom('[href="/abc000000000000000000001/edit"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Delete" button', function() {
|
it('should display a "Delete" button', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/delete"]').length, 1);
|
assert.strictEqual(this.last.dom('[href="/abc000000000000000000001/delete"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Run" button', function() {
|
it('should display a "Run" button', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/run"]').length, 1);
|
assert.strictEqual(this.last.dom('[href="/abc000000000000000000001/run"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Download CSV" button for the latest result', function() {
|
it('should display a "Download CSV" button for the latest result', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/def000000000000000000001.csv"]').length, 1);
|
assert.strictEqual(this.last.dom('[href="/abc000000000000000000001/def000000000000000000001.csv"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Download JSON" button for the latest result', function() {
|
it('should display a "Download JSON" button for the latest result', function() {
|
||||||
assert.strictEqual(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/def000000000000000000001.json"]').length, 1);
|
assert.strictEqual(this.last.dom('[href="/abc000000000000000000001/def000000000000000000001.json"]').length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display links to all results', function() {
|
it('should display links to all results', function() {
|
||||||
assert.isDefined(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/def000000000000000000001"]')[0]);
|
assert.isDefined(this.last.dom('[href="/abc000000000000000000001/def000000000000000000001"]').eq(0));
|
||||||
assert.isDefined(this.last.dom.querySelectorAll('[href="/abc000000000000000000001/def000000000000000000003"]')[0]);
|
assert.isDefined(this.last.dom('[href="/abc000000000000000000001/def000000000000000000003"]').eq(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display errors', function() {
|
it('should display errors', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=task-errors]')[0];
|
var elem = this.last.dom('[data-test=task-errors]').eq(0);
|
||||||
assert.isDefined(elem);
|
assert.isDefined(elem);
|
||||||
assert.match(elem.textContent, /errors \( 1 \)/i);
|
assert.match(elem.text(), /errors \( 1 \)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display warnings', function() {
|
it('should display warnings', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=task-warnings]')[0];
|
var elem = this.last.dom('[data-test=task-warnings]').eq(0);
|
||||||
assert.isDefined(elem);
|
assert.isDefined(elem);
|
||||||
assert.match(elem.textContent, /warnings \( 2 \)/i);
|
assert.match(elem.text(), /warnings \( 2 \)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display notices', function() {
|
it('should display notices', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=task-notices]')[0];
|
var elem = this.last.dom('[data-test=task-notices]').eq(0);
|
||||||
assert.isDefined(elem);
|
assert.isDefined(elem);
|
||||||
assert.match(elem.textContent, /notices \( 3 \)/i);
|
assert.match(elem.text(), /notices \( 3 \)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -93,15 +93,15 @@ describe('GET /<task-id>', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display a "Run" button', function() {
|
it('should display a "Run" button', function() {
|
||||||
var elem = this.last.dom.querySelectorAll('[data-test=run-task]');
|
var elem = this.last.dom('[data-test=run-task]');
|
||||||
assert.strictEqual(elem.length, 1);
|
assert.strictEqual(elem.length, 1);
|
||||||
assert.strictEqual(elem[0].getAttribute('href'), '/abc000000000000000000003/run');
|
assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000003/run');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a message indicating that there are no results', function() {
|
it('should display a message indicating that there are no results', function() {
|
||||||
var alert = this.last.dom.querySelectorAll('[data-test=alert]')[0];
|
var alert = this.last.dom('[data-test=alert]').eq(0);
|
||||||
assert.isDefined(alert);
|
assert.isDefined(alert);
|
||||||
assert.match(alert.textContent, /there are no results to show/i);
|
assert.match(alert.text(), /there are no results to show/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -36,9 +36,9 @@ describe('GET /<task-id>/run', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display a success message', function() {
|
it('should display a success message', function() {
|
||||||
var alert = this.last.dom.querySelectorAll('[data-test=alert]')[0];
|
var alert = this.last.dom('[data-test=alert]').eq(0);
|
||||||
assert.isDefined(alert);
|
assert.isDefined(alert);
|
||||||
assert.match(alert.textContent, /new results are being generated/i);
|
assert.match(alert.text(), /new results are being generated/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -19,20 +19,20 @@ var moment = require('moment');
|
|||||||
|
|
||||||
module.exports = helper;
|
module.exports = helper;
|
||||||
|
|
||||||
function helper(register) {
|
function helper(hbs) {
|
||||||
|
|
||||||
// Format a date with Moment
|
// Format a date with Moment
|
||||||
register('date-format', function(context, block) {
|
hbs.registerHelper('date-format', function(context, block) {
|
||||||
var format = block.hash.format || 'YYYY-MM-DD HH:mm:ss';
|
var format = block.hash.format || 'YYYY-MM-DD HH:mm:ss';
|
||||||
return moment(context).format(format);
|
return moment(context).format(format);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get a relative date
|
// Get a relative date
|
||||||
register('date-relative', function(context) {
|
hbs.registerHelper('date-relative', function(context) {
|
||||||
return moment(context).fromNow();
|
return moment(context).fromNow();
|
||||||
});
|
});
|
||||||
|
|
||||||
register('date-timestamp', function(context) {
|
hbs.registerHelper('date-timestamp', function(context) {
|
||||||
return moment(context).valueOf();
|
return moment(context).valueOf();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
module.exports = helper;
|
module.exports = helper;
|
||||||
|
|
||||||
function helper(register) {
|
function helper(hbs) {
|
||||||
|
|
||||||
// Convert a string to lower-case
|
// Convert a string to lower-case
|
||||||
register('lowercase', function(context) {
|
hbs.registerHelper('lowercase', function(context) {
|
||||||
return context.toLowerCase();
|
return context.toLowerCase();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -17,10 +17,10 @@
|
|||||||
|
|
||||||
module.exports = helper;
|
module.exports = helper;
|
||||||
|
|
||||||
function helper(register) {
|
function helper(hbs) {
|
||||||
|
|
||||||
// Simplify url by removing (eg http://, https://, trailing slashes) from url
|
// Simplify url by removing (eg http://, https://, trailing slashes) from url
|
||||||
register('simplify-url', function(context) {
|
hbs.registerHelper('simplify-url', function(context) {
|
||||||
return context.replace(/^https?:\/\//i, '').replace(/\/$/, '').toLowerCase();
|
return context.replace(/^https?:\/\//i, '').replace(/\/$/, '').toLowerCase();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ along with pa11y-dashboard. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
<div class="col-md-6 col-md-offset-3 filter-toggle no-js-hide text-center">
|
<div class="col-md-6 col-md-offset-3 filter-toggle no-js-hide text-center">
|
||||||
<label for="filter-input" class="filter-trigger" data-toggle="collapse" data-target="#filter-input">Filter<span class="glyphicon glyphicon-filter"></span>
|
<label for="task-filter" class="filter-trigger" data-toggle="collapse" data-target="#filter-input">Filter<span class="glyphicon glyphicon-filter"></span>
|
||||||
</label>
|
</label>
|
||||||
<div id="filter-input" class="collapse">
|
<div id="filter-input" class="collapse">
|
||||||
<input class="form-control" id="task-filter" type="text" data-role="input" placeholder="Type filter term (name or standard)"/>
|
<input class="form-control" id="task-filter" type="text" data-role="input" placeholder="Type filter term (name or standard)"/>
|
||||||
|
@@ -74,6 +74,16 @@ along with pa11y-dashboard. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group clearfix">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 col-sm-4 col-xs-6">
|
||||||
|
<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}}"/>
|
||||||
|
<em>(Note: default wait time is 0ms)</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<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">
|
||||||
@@ -92,7 +102,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/springernature/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></p>
|
||||||
|
|
||||||
<div class="standards-lists">
|
<div class="standards-lists">
|
||||||
{{#standards}}
|
{{#standards}}
|
||||||
|
@@ -19,7 +19,7 @@ along with pa11y-dashboard. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
<div class="row clearfix">
|
<div class="row clearfix">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<h1 class="h2 crunch-top">{{task.name}}</h1>
|
<h1 class="h2 crunch-top">{{task.name}}</h1>
|
||||||
<p class="h4">{{simplify-url task.url}}<span class="h5"> ({{task.standard}})</span></p>
|
<p class="h4"><a href="{{task.url}}">{{simplify-url task.url}}</a><span class="h5"> ({{task.standard}})</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="run-details task-header clearfix">
|
<div class="run-details task-header clearfix">
|
||||||
<div class="col-md-12 clearfix">
|
<div class="col-md-12 clearfix">
|
||||||
|
@@ -86,6 +86,16 @@ along with pa11y-dashboard. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group clearfix">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 col-sm-4 col-xs-6">
|
||||||
|
<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}}"/>
|
||||||
|
<em>(Note: default wait time is 0ms)</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<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">
|
||||||
@@ -104,7 +114,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/springernature/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></p>
|
||||||
|
|
||||||
<div class="standards-lists">
|
<div class="standards-lists">
|
||||||
{{#standards}}
|
{{#standards}}
|
||||||
|
Reference in New Issue
Block a user