Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@
'use strict';

const fs = require('fs');
const csvToArray = require('./utils/csvToArray');
const jsonPath = `./config/${process.env.NODE_ENV || 'development'}.json`;

const DEFAULT_RUNNER = 'htmlcs';

if (fs.existsSync(jsonPath)) {
const jsonConfig = require(jsonPath);
const runners = csvToArray(env('RUNNERS', jsonConfig.runners));

module.exports = {
database: env('DATABASE', jsonConfig.database),
host: env('HOST', jsonConfig.host),
port: Number(env('PORT', jsonConfig.port)),
runners: runners.length ? runners : [DEFAULT_RUNNER],
cron: env('CRON', jsonConfig.cron),
chromeLaunchConfig: jsonConfig.chromeLaunchConfig || {},
numWorkers: jsonConfig.numWorkers || 2
Expand All @@ -33,6 +38,7 @@ if (fs.existsSync(jsonPath)) {
database: env('DATABASE', 'mongodb://localhost/pa11y-webservice'),
host: env('HOST', '0.0.0.0'),
port: Number(env('PORT', '3000')),
runners: csvToArray(env('RUNNERS', DEFAULT_RUNNER)),
cron: env('CRON', false),
chromeLaunchConfig: {},
numWorkers: Number(env('NUM_WORKERS', '2'))
Expand All @@ -41,5 +47,5 @@ if (fs.existsSync(jsonPath)) {

function env(name, defaultValue) {
const value = process.env[name];
return (typeof value === 'string' ? value : defaultValue);
return typeof value === 'string' ? value : defaultValue;
}
17 changes: 8 additions & 9 deletions config/development.sample.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"database": "mongodb://localhost/pa11y-webservice-dev",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *",
"chromeLaunchConfig": {
"args": [
"--no-sandbox"
]
}
"database": "mongodb://localhost/pa11y-webservice-dev",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *",
"runners": "htmlcs",
"chromeLaunchConfig": {
"args": ["--no-sandbox"]
}
}
11 changes: 6 additions & 5 deletions config/production.sample.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"database": "mongodb://localhost/pa11y-webservice",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *",
"chromeLaunchConfig": {}
"database": "mongodb://localhost/pa11y-webservice",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *",
"runners": "htmlcs",
"chromeLaunchConfig": {}
}
9 changes: 5 additions & 4 deletions config/test.sample.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"database": "mongodb://localhost/pa11y-webservice-test",
"host": "0.0.0.0",
"port": 3000,
"chromeLaunchConfig": {}
"database": "mongodb://localhost/pa11y-webservice-test",
"host": "0.0.0.0",
"port": 3000,
"runners": "htmlcs",
"chromeLaunchConfig": {}
}
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ app(config, (error, initialisedApp) => {
console.log(grey('mode: %s'), process.env.NODE_ENV);
console.log(grey('uri: %s'), initialisedApp.server.info.uri);
console.log(grey('database: %s'), dbConnectionString);
console.log(grey('runners: %s'), config.runners);
console.log(grey('cron: %s'), config.cron);

if (error) {
Expand Down
142 changes: 83 additions & 59 deletions model/task.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,30 @@
const {grey} = require('kleur');
const {ObjectID} = require('mongodb');
const pa11y = require('pa11y');
const csvToArray = require('../utils/csvToArray');

// Task model
module.exports = function(app, callback) {
app.db.collection('tasks', function(errors, collection) {
collection.ensureIndex({
name: 1,
url: 1,
standard: 1
}, {
w: -1
});
collection.ensureIndex(
{
name: 1,
url: 1,
standard: 1
},
{
w: -1
}
);
const model = {

collection: collection,

// Create a task
create: function(newTask) {
newTask.headers = model.sanitizeHeaderInput(newTask.headers);

return collection.insert(newTask)
return collection
.insert(newTask)
.then(result => {
return model.prepareForOutput(result.ops[0]);
})
Expand Down Expand Up @@ -79,7 +83,8 @@ module.exports = function(app, callback) {
}

// http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#findOne
return collection.findOne({_id: id})
return collection
.findOne({_id: id})
.then(task => {
return model.prepareForOutput(task);
})
Expand Down Expand Up @@ -118,7 +123,8 @@ module.exports = function(app, callback) {
taskEdits.headers = model.sanitizeHeaderInput(edits.headers);
}

return collection.update({_id: id}, {$set: taskEdits})
return collection
.update({_id: id}, {$set: taskEdits})
.then(updateCount => {
if (updateCount < 1) {
return 0;
Expand All @@ -128,10 +134,9 @@ module.exports = function(app, callback) {
date: now,
comment: edits.comment || 'Edited task'
};
return model.addAnnotationById(idString, annotation)
.then(() => {
return updateCount;
});
return model.addAnnotationById(idString, annotation).then(() => {
return updateCount;
});
})
.catch(error => {
console.error(`model:task:editById failed, with id: ${id}`);
Expand All @@ -142,20 +147,28 @@ module.exports = function(app, callback) {

// Add an annotation to a task
addAnnotationById: function(id, annotation) {
return model.getById(id)
return model
.getById(id)
.then(task => {
if (!task) {
return 0;
}
id = new ObjectID(id);
if (Array.isArray(task.annotations)) {
return collection.update({_id: id}, {$push: {annotations: annotation}});
return collection.update(
{_id: id},
{$push: {annotations: annotation}}
);
}
return collection.update({_id: id}, {$set: {annotations: [annotation]}});

return collection.update(
{_id: id},
{$set: {annotations: [annotation]}}
);
})
.catch(error => {
console.error(`model:task:addAnnotationById failed, with id: ${id}`);
console.error(
`model:task:addAnnotationById failed, with id: ${id}`
);
console.error(error.message);
return null;
});
Expand All @@ -169,7 +182,8 @@ module.exports = function(app, callback) {
console.error('ObjectID generation failed.', error.message);
return null;
}
return collection.deleteOne({_id: id})
return collection
.deleteOne({_id: id})
.then(result => {
return result ? result.deletedCount : null;
})
Expand All @@ -182,45 +196,53 @@ module.exports = function(app, callback) {

// Run a task by ID
runById: function(id) {
return model.getById(id).then(async task => {
const pa11yOptions = {
standard: task.standard,
includeWarnings: true,
includeNotices: true,
timeout: (task.timeout || 30000),
wait: (task.wait || 0),
ignore: task.ignore,
actions: task.actions || [],
chromeLaunchConfig: app.config.chromeLaunchConfig || {},
headers: task.headers || {},
log: {
debug: model.pa11yLog(task.id),
error: model.pa11yLog(task.id),
info: model.pa11yLog(task.id),
log: model.pa11yLog(task.id)
}
};

// eslint-disable-next-line dot-notation
if (task.username && task.password && !pa11yOptions.headers['Authorization']) {
const encodedCredentials = Buffer.from(`${task.username}:${task.password}`)
.toString('base64');
return model
.getById(id)
.then(async task => {
const pa11yOptions = {
standard: task.standard,
includeWarnings: true,
includeNotices: true,
timeout: task.timeout || 30000,
wait: task.wait || 0,
ignore: task.ignore,
actions: task.actions || [],
runners: csvToArray(app.config.runners),
chromeLaunchConfig: app.config.chromeLaunchConfig || {},
headers: task.headers || {},
log: {
debug: model.pa11yLog(task.id),
error: model.pa11yLog(task.id),
info: model.pa11yLog(task.id),
log: model.pa11yLog(task.id)
}
};

// eslint-disable-next-line dot-notation
pa11yOptions.headers['Authorization'] = `Basic ${encodedCredentials}`;
}
if (
task.username &&
task.password &&
!pa11yOptions.headers.Authorization
) {
const encodedCredentials = Buffer.from(
`${task.username}:${task.password}`
).toString('base64');

if (task.hideElements) {
pa11yOptions.hideElements = task.hideElements;
}
// eslint-disable-next-line dot-notation
pa11yOptions.headers.Authorization = `Basic ${encodedCredentials}`;
}

const pa11yResults = await pa11y(task.url, pa11yOptions);
if (task.hideElements) {
pa11yOptions.hideElements = task.hideElements;
}

const pa11yResults = await pa11y(task.url, pa11yOptions);

const results = app.model.result.convertPa11y2Results(pa11yResults);
results.task = new ObjectID(task.id);
results.ignore = task.ignore;
return app.model.result.create(results);
})
const results = app.model.result.convertPa11y2Results(pa11yResults);
results.task = new ObjectID(task.id);
results.ignore = task.ignore;
return app.model.result.create(results);
})
.catch(error => {
console.error(`model:task:runById failed, with id: ${id}`);
console.error(error.message);
Expand All @@ -237,8 +259,8 @@ module.exports = function(app, callback) {
id: task._id.toString(),
name: task.name,
url: task.url,
timeout: (task.timeout ? parseInt(task.timeout, 10) : 30000),
wait: (task.wait ? parseInt(task.wait, 10) : 0),
timeout: task.timeout ? parseInt(task.timeout, 10) : 30000,
wait: task.wait ? parseInt(task.wait, 10) : 0,
standard: task.standard,
ignore: task.ignore || [],
actions: task.actions || []
Expand All @@ -260,7 +282,10 @@ module.exports = function(app, callback) {
try {
output.headers = JSON.parse(task.headers);
} catch (error) {
console.error('Header input contains invalid JSON:', task.headers);
console.error(
'Header input contains invalid JSON:',
task.headers
);
console.error(error.message);
}
} else {
Expand Down Expand Up @@ -296,7 +321,6 @@ module.exports = function(app, callback) {
console.log(grey(messageString));
};
}

};
callback(errors, model);
});
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"data",
"model",
"route",
"task"
"task",
"utils"
]
}
6 changes: 2 additions & 4 deletions test/integration/startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ const config = require('../../config/test.json');
const app = require('../../app');

describe('pa11y-service startup', function() {

it('should start the service and call the callback', done => {
const modifiedConfig = {
database: config.database,
host: config.host,
port: config.port + 10
port: config.port + 10,
runners: config.runners
};

app(modifiedConfig, (error, webservice) => {
Expand All @@ -37,5 +37,3 @@ describe('pa11y-service startup', function() {
});
});
});


Loading