123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- const CDP = require('chrome-remote-interface');
- const axeCore = require('axe-core');
- const assert = require('assert');
- const { parse: parseURL } = require('url');
- // Cheap URL validation
- const isValidURL = input => {
- const u = parseURL(input);
- return u.protocol && u.host;
- };
- const example = async url => {
- // eslint-disable-next-line new-cap
- const client = await CDP();
- const { Runtime: runtime, Page: page } = client;
- let results;
- try {
- await page.enable();
- await runtime.enable();
- await page.navigate({ url });
- // This function is injected into the browser and is responsible for
- // running `axe-core`.
- const browserCode = () => {
- /* eslint-env browser */
- return new Promise((resolve, reject) => {
- const axe = window.axe;
- if (!axe) {
- throw new Error('Unable to find axe-core');
- }
- // Finally, run axe-core
- axe
- .run()
- // For some reason, when resolving with an object, CDP ignores
- // its value (`results.result.value` is undefined). By
- // `JSON.stringify()`ing it, we can `JSON.parse()` it later on
- // and return a valid results set.
- .then(results => JSON.stringify(results))
- .then(resolve)
- .catch(reject);
- });
- };
- // Inject axe-core
- await runtime.evaluate({
- expression: axeCore.source
- });
- // Run axe-core
- const ret = await runtime.evaluate({
- expression: `(${browserCode})()`,
- awaitPromise: true
- });
- // re-parse
- results = JSON.parse(ret.result.value);
- } catch (err) {
- // Ensure we close the client before exiting the fn
- client.close();
- throw err;
- }
- client.close();
- return results;
- };
- // node axe-cdp.js <url>
- const url = process.argv[2];
- assert(isValidURL(url), 'Invalid URL');
- example(url)
- .then(results => {
- console.log(results);
- })
- .catch(err => {
- console.error('Error running axe-core:', err.message);
- process.exit(1);
- });
|