Extract all API package files, then upload or transfer to your web server. The files in the 'htdocs' directory must be accessible via the web server. If necessary, set up an Apache or Nginx site or virtual directory to point to the directory that contains request.php, or place these files in an existing web director. The 'core' directory should not be publicly accessible and must contain the Puppeteer library (see below).
The WAVE API requires the Puppeteer Node library.
To install Puppeteer, run the following in the API's "/core/" directory:
npm i puppeteer
You may need to install Node.js and npm first. Node v7.6.0 or greater is required. For Linux, it's best to use a NodeSource installer.
Depending on your operating system, you likely will need to install dependencies for the Chromium browser to run. Read details on finding and installing Chromium dependencies. On Debian/Ubuntu, the following command should install all required dependencies:
sudo apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
For Amazon EC2 Linux AMI, read these instructions.
If you are exclusively using the browserless.io service, you can instead install Puppeteer-core, which does not include the Chromium browser:
npm i puppeteer-core
See https://wave.webaim.org/api/details for all parameters and API usage details (you will, of course, need to modify URLs to point to your local installation). Additionally, the stand-alone API allows you to pass additional parameters as defined above. If set, these will override any parameters set in the user.config.json file.
The WAVE Documentation API may be freely accessed via the public WAVE website as documented at https://wave.webaim.org/api/details#documentation. A JSON object for all WAVE items (including documentation) for use within your application can be provided upon request.
Puppeteer scripts can be run before and after the page to be evaluated is loaded and rendered. Pre-load scripts allow you to perform processes such as logging in to a web site or setting cookies or local storage data (perhaps with session information) - useful if the page to be evaluated requires authentication (complex authentication, such as two-factor, may not work directly). Post-load scripts allow you to manipulate page content, fill out forms, trigger error messages, trigger Single Page App state changes, etc. before the page is analyzed by WAVE.
Scripts must be saved in the /temp/scripts/ directory with .js extension. The script template must be formatted as follows:
module.exports = async (page) => {
YOUR PUPPETEER COMMANDS HERE
return page;
};
To run pre- or post-load scripts, append the prescript
and/or postscript
GET parameters to your API request - request.php?key=YOURKEY&url=YOURURL&prescript=mypreloadscript.js&postscript=mypostloadscript.js
IMPORTANT: Because Puppeteer scripts give full control to the Chromium browser within the API, care is in order to ensure that access is limited.
Many examples of Puppeteer scripts are available at https://github.com/checkly/puppeteer-examples. You can record page interactions using the Puppeteer Recorder Chrome extension.
DO NOT include high-level Puppeteer commands, such as async
, const puppeteer = require('puppeteer');
, const browser
, const page
, await browser.close()
, etc. - these are handled by the API already. Pre-load scripts will typically begin with a page.goto
to open a page (such as a log-in page). Post-load scripts will NOT include page.goto
, but will manipulate the content of or interact with the page being evaluated. Element selectors (found using Puppeteer Recorder or Developer Tools) are used to identify components within the page.
module.exports = async (page) => {
await page.goto('https://mysite.com/login');
await page.waitFor('#username');
await page.type('#username', 'MyUsername');
await page.waitFor('#password');
await page.type('#password', 'MyP@55word');
await page.click('.login-button');
await page.waitForSelector('#maincontent');
return page;
};
This prescript loads the login page, ensures that the the username and password fields are available, types the username and password into the appropriate fields, clicks the log in button (class="login-button"
), and then waits for the "id=maincontent"
element to be loaded in the resulting page. The page to be evaluated will be loaded with the authentication and cookies in place.
For sites that rely on cookies to verify authentication information, you can capture the cookie values via Developer Tools or by the EditThisCookie browser extension, then set this cookie data in a prescript.
module.exports = async (page) => {
const cookie = {
"domain": "webaim.org",
"hostOnly": true,
"httpOnly": false,
"name": "sessionid",
"path": "/",
"sameSite": "no_restriction",
"secure": false,
"session": true,
"storeId": "0",
"value": "01234567890",
"id": 1
}
await page.setCookie(cookie)
return page;
};
With the sessionid cookie in place, you can then evaluate pages on the site that would otherwise require separate authentication.
Some sites use Local Storage, rather than cookies, to store authentication data. This can also be captured and injected before the page is evaluated.
module.exports = async (page) => {
let json ={"currentUser":"{\"username\":\"username@domain.org\",\"token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOi\"}"};
await page.evaluateOnNewDocument(json => {
localStorage.clear();
for (let key in json)
localStorage.setItem(key, json[key]);
}, json);
return page;
};
With a session data in place, you can then evaluate pages on the site that would otherwise require authentication.
module.exports = async (page) => {
await page.waitFor('#search');
await page.type('#search', 'John');
await page.click('#search-button');
await page.waitFor('#search-results');
await page.click('#search-results > div > .details:nth-child(4)');
await page.waitFor(1000);
return page;
};
This Puppeteer script will wait for the id="search"
input element, enter the word "John" into this field, click the search button, wait for the search results element, then click the 4th button (within class="details"), then wait 1000 milliseconds for the details dialog to appear. After the post-script has completed, the API will wait evaldelay milliseconds (default 250) before analyzing the page.
Scripts are currently experimental! They may significantly increase API processing time and may result in errors, especially if the page content is lost before or is changing during the API analysis. You can check for internal errors by appending the ?debug=true GET parameter to your request, or can save a screen shot to /temp/screenshots/temp.png at any point during the script process with the following Puppeteer script command:
await page.screenshot({path: wave.api.config['temp_path'] + "screenshots/temp.png", fullPage: true});
By licensing the WAVE Accessibility Tool stand-alone online web service, API, and/or related systems (hereafter referred to as WAVE), you acknowledge that you have read, understood, and agree to be bound by the WAVE Terms of Use for your license.