Here is a working JavaScript example, From Zero to Hero, of creating a web automation accessibility test using our Level Access Testing SDK.
On this page:
- About this example
- Prerequisites
- Sample test script with Selenium
- Create a basic script (web automation file)
- SDK integration
- High-level script overview: What your file should look like
About this example
Level Access Testing SDK for JavaScript is delivered as a single .js file.
To learn more, go to https://tools.levelaccess.net/continuum/docs/latest/jsdoc/Continuum.js.html#line4531. Note that each programming language has at least one package management library.
Note: If you're using server-side JavaScript via something like Node, you must initialize Access Continuum differently than you would for client-side JavaScript via something like Karma, where the latter necessitates that Continuum be injected directly into the pages to be tested in a web browser.
Prerequisites
The following table lists the prerequisites you must meet:
Prerequisite |
Description |
Google Chrome > v76.0 |
A popular web browser that you might already have installed. |
Node.JS > v16.0 |
A popular server-side scripting environment for JavaScript. |
NPM > v10.10: |
The node.js package manager. If you don't know the version of Node or NPM that you’re running, open a terminal and run the following commands: node --version npm --version If you need to install node.js and npm for your own computer, use this procedure: Downloading and installing Node.js and npm. |
Sample test script with Selenium
Selenium is a core component of our SDK. In this example, the test script performs these steps:
- Navigate to duckduckgo.com.
- Scan the homepage.
- Type in a search term.
- Click search.
Create a basic script (web automation file)
To create a basic script, web_automation.js file, we need to configure npm, node, and ~/.npmrc.
To start creating a basic script:
-
Create a new directory and change directories, cd into it.
mkdir level-access-sdk-testing && cd level-access-sdk-testing -
Start a new project. Run this command:
npm init -y -
Install selenium. Run this command:
npm install --save-dev selenium-webdriver - Using a basic (not rich) text editor, create a new file, and save it to the same directory: web_automation.js
- Copy and paste the below into the file, and then save the file.
const { Builder, By } = require('selenium-webdriver');
// Define a function that automates a test.
async function web_automation() {
// Create a new web driver object to talk to chrome
let driver = await new Builder().forBrowser("chrome").build();
// .get tells the driver to make the web browser go to a website
await driver.get("https://www.duckduckgo.com");
// .findElement will locate an element using By.css
// .sendKeys will type to that field found
await driver.findElement(By.css("input[name='q']")).sendKeys("camping equipment");
// Find the submit button and click it
await driver.findElement(By.css("button[type='submit']")).click();
// Pause for 10 seconds (10,000 ms), or else the window will close automatically.
// Not necessary, but nice to see what the browser is doing at the end.
await driver.sleep(10000);
// Close the web browser driver
driver.quit()
}
// Run the function above.
web_automation();-
Run the file in the terminal window:
node web_automation.jsNote: For this to work on OSX, chromedriver nneds to be the app that the fix is run on.
You should see a Chrome browser appear, navigate to duckduckgo.com, and search for camping equipment (a search term in the file).
We now have the most basic web automation configuration. Our file structure should now look like this:
level-access-sdk-testing/
package.json
package-lock.json
web_automation.jsThe package-lock file appears after the project is initialized and installed.
Note: The file in this article contains multiple comments that describe what each line is doing. The line of code await driver.sleep(10000); is used to give you time to see what the browser is doing before the script completes and the browser closes. It delays for 10 seconds (10000 milliseconds). If you really wanted to, you could sprinkle that line anywhere within the web_automation() function to pause at any time:
// Pause for 10 seconds (10,000 ms), or else the window will close automatically.
// Not necessary, but nice to see what the browser is doing at the end.
SDK integration
This section describes how to add Level Access Testing SDKs into your testing environment.
You must complete these tasks:
- Download and install the SDK
- Install a specific version of the SDK
- Configure SDK
- Use the SDK to test for accessibility
Download and install the SDK
The following table describes each term in the SDK package installation statement:
Term |
Definition |
npm |
The node package manager, which executes all commands, keywords, and flags. |
install |
The npm command to install a package. |
--save-dev |
A flag that tells npm to add what is being installed as a dependency to the project in the current directory. |
@continuum/continuum-javascript-professional |
The package to install. |
@6.7.0 |
A specific version of the Continuum SDK to install.
|
To download and install the SDK:
- Check to see if you have an .npmrc (NPM Runtime Configuration) file in your home directory. If not, create one using a plain text editor such as Notepad or vi (not Word or WordPad). To learn more about the file, go to npmrc. On *nix type systems your home directory is written as ~/. Hence, this file path should be ~/.npmrc.
- Another *nix feature is that files starting with a period (.) are hidden by default. Hence, if you are in the ~/ directory and type ls you won’t see your .npmrc file. Instead, you'll need to do ls -a to show all files, including your hidden .npmrc file.
- If your .npmrc file doesn’t already have it, add the Continuum repository to gain access by doing the following steps:
- Log in to the Level Access Platform using your favorite web browser
- From the platform navigation menu, under Manage, select Tools & Integrations, and then SDK.
- Under the JavaScript logo and title, select Download and Install.
-
Copy the two Continuum repository access lines using the Copy button at the right. The lines should look like this:
@continuum:registry=https://npm.levelaccess.net/continuum/ //npm.levelaccess.net/continuum/:_authToken=a2B3c5t67HjklThe value of the authToken is unique to your account. Do not share it with anyone else.
-
Check available versions. With the Continuum repository added to your .npmrc with a valid token, you can now check to see what versions are available. To do so, run this command:
npm view @continuum/continuum-javascript-professional versions --json This should return a list that looks something like this: [ '4.0.0', '4.0.1', '4.0.2', '4.1.0', '4.2.0', '4.3.0', '4.4.0', '4.5.0', '4.5.1', '4.7.0', '4.7.1', '4.7.2', '4.8.0', '4.9.0', '5.0.0', '5.0.1', '5.1.0', '5.1.1', '5.1.2', '6.0.0', '6.1.0', '6.1.1', '6.1.2', '6.2.0', '6.3.0', '6.4.0', '6.5.0', '6.6.0', '6.7.0', '6.8.0', '6.9.0', '7.0.0', '7.1.0', '7.2.0', '7.3.0' ] -
You can now install the latest version of Continuum to have it included in your package .json. Run this command:
npm install --save-dev @continuum/continuum-javascript-professional
Install a specific version of the SDK
To install a specific version of Access Continuum, add it to the end of the command like this:
npm install --save-dev @continuum/continuum-javascript-professional@6.7.0Configure SDK
We'll create a new file in the project root directory: continuum.conf.js.
The following table describes the properties that you need to set in the continuum.conf.js file.
Key |
Definition |
orgInstanceUrl |
The base organization URL, where the Level Access Platform services are located. This property is required and will be used for all scan sessions. |
apiKey |
The API key used in requests to the Level Access Platform services. This property is required and used for all scan sessions. To learn more about how to find the apiKey, go to Find API-parameters in the platform. |
workspaceId |
The id or the workspace, which is when a scan session opens in the Level Access Platform. This property is optional and can be set here to apply to all scan sessions or provided / overridden programmatically when opening a new scan session. |
digitalPropertyId |
The id or the digital property used when a scan session opens in the Level Access Platform. This property is optional and can be set here to apply to all scan sessions or provided / overridden programmatically, when a new scan session opens. |
scanTagId |
The id or the scan tag used when a new scan session opens in the Level Access Platform. This property is optional. It can be set here to apply to all scan sessions or provided / overridden programmatically when a new scan session opens. To learn more about how to find the ScanTag ID, go to Find API-parameters in the platform. |
To configure the SDK:
- Paste the following into the continuum.conf.js file:
window.LevelAccess_AccessContinuumConfiguration = {
"accessEngineType": "professional",
"ampInstanceUrl": "https://amp.levelaccess.net",
"defaultStandardIds": [
610, /* WCAG 2.0 Level A */
611, /* WCAG 2.0 Level AA */
612, /* WCAG 2.0 Level AAA */
1387, /* WCAG 2.1 Level A */
1388, /* WCAG 2.1 Level AA */
1389, /* WCAG 2.1 Level AAA */
2127, /* WCAG 2.2 Level A */
2128, /* WCAG 2.2 Level AA */
2129 /* WCAG 2.2 Level AAA */
1140, /* Section 508 and 255 (Revised 2017) */
1471 /* WCAG 2.0 Level A & AA Baseline */
],
"includePotentialAccessibilityConcerns": false,
"ampApiToken": null,
"proxy": {
"host": null,
"port": null,
"username": null,
"password": null
},
"accessibilityConcerns": {
"includePotentialConcerns": false,
"format": "amp"
},
"levelAccessPlatform": {
"orgInstanceUrl": "" ,
"apiKey": "",
"workspaceId": "",
"digitalPropertyId": "",
"scanTagId": ""
}
}
- Review the bottom of the continuum.conf.js file. Find the following code, which needs to be filled in:
"levelAccessPlatform": {
"orgInstanceUrl": "",
"apiKey": "",
"workspaceId": "",
"digitalPropertyId": "",
"scanTagId": ""
}The following table describes each property:
| Property | Description |
orgInstanceUrl |
Sets the starting URL of your instance of the Level Access Platform. Required for scans to work. Example orgInstanceUrl: https://your_org_name.hub.essentia11y.com |
apiKey |
Your personal API key that you create in the Level Access Platform. Required for scans to work. It is tied to your user account and expires every six months. To create your apiKey:
Example apiKey: 4r44g305-cdd1-4513-a76b-478z22b3ejb5 |
workspaceId |
Set the ID of the Workspace you want the results to be stored in. Setting it here makes it the default for all scans unless you supply a different workspaceId when making the individual scan calls. The value must be provided either in the config file or in the scan call for scans to work. To find the ID for your Workspace:
Example workspaceId: 63416cfec1505527n10284a3 |
digitalPropertyId |
Sets the ID of the digital asset (digital property) you want the results to be stored in. This digital asset must exist in the Workspace you specified. Setting it here makes it the default for all scans unless you supply a different digitalPropertyId when making the individual scan calls. The value must be provided either in the config file or in the scan call for scans to work. To find the ID for your Digital Asset (previously known as Digital Property):
Example digitalPropertyId: 67533274378e413e26ff5g69 |
scanTagId |
Sets the ID of the Scan Tag you want the results to be labeled with. This Scan Tag must exist in the Workspace you specified. Setting it here makes it the default for all scans unless you supply a different scanTagId when making the individual scan calls. The value must be provided either in the config file or in the scan call for scans to work. To find the ID for your Scan Tag:
Example scanTagId: 6017fa50g984be58ffda7f85 |
Use the SDK to test for accessibility
Now that your continuum.conf.js file is populated with the needed values, we can begin feathering Level Access Testing SDK into your automated testing project. This involves importing the SDK, initializing it, and sprinkling accessibility testing at points of interest while the automation is running. Finally, send all the results to the Level Access Platform for review and processing.
To test for accessibility:
- Open the web_automation.js file created earlier. To import the SDK into your project, add the following code as the second line of the file:
const {Continuum} = require('@continuum/continuum-javascript-professional');This code imports the object Continuum from the file path @continuum/continuum-javascript-professional. It pulls this in from a folder within the node_modules/ directory.
- After we’ve initialized the driver, we need the following line in the file to import our SDK configuration file:
await Continuum.setUp(driver, require('path').resolve(__dirname, "./continuum.conf.js"));
Note: We are assuming continuum.conf.js is in the same directory as web_automation.js. If you decide to store your continuum.conf.js elsewhere you must adjust the path in the call to .setUp(), so that it can find where you placed it.
- Modify the web_automation.js file to add the following line of code to run an accessibility scan at points of interest in the automation:
await Continuum.runAllTests();Typically, we want to do this after the page is loaded, and then again, after the search was run.
The main idea is:
Get your web page into a condition you want to test.
Run the accessibility test.
Repeat.
- View the results in the console.
At this point we’ve pulled the SDK into our project, initialized them, and ran scans at interesting points during the automation. Now, we need to place these results somewhere, so that we can look at them.
The simplest way is to log them to the console. To do so, add the following lines of code to the end of the web_automation.js file, inside the web_automation() function:
const console_assertions = Continuum.getAssertions();
console.log(console_assertions);Your web_automation.js file should now look something like this:
const { Builder, By } = require('selenium-webdriver');
const {Continuum} = require('@continuum/continuum-javascript-professional');
// Define a function that automates a test.
async function web_automation() {
// Create a new web driver object to talk to chrome
let driver = await new Builder().forBrowser("chrome").build();
// Setup Continuum using the relative path of the continuum.conf.js file.
await Continuum.setUp(driver, require('path').resolve(__dirname, "./continuum.conf.js"));
// .get tells the driver to make the web browser go to a website
await driver.get("https://www.duckduckgo.com");
// Test the current page for accessibility
await Continuum.runAllTestsForAssertions();
// .findElement will locate an element using By.css
// .sendKeys will type to that field found
await driver.findElement(By.css("input[name='q']")).sendKeys("camping equipment");
// Find the submit button and click it (searches and redirects the page)
await driver.findElement(By.css("button[type='submit']")).click();
// Test the current page for accessibility
await Continuum.runAllTestsForAssertions();
// Pause for 10 seconds (10,000 ms), or else the window will close automatically.
// Not necessary, but nice to see what the browser is doing at the end.
await driver.sleep(10000);
// Close the web browser driver
driver.quit()
// Output all the findings to the console
const console_assertions = Continuum.getAssertions();
console.log(console_assertions);
}
// Run the function above.
web_automation();- To execute your automated testing, now enriched with accessibility checks, run the following command in your shell:
node web_automation.jsYou should see output that looks like this:
[
{ testId: '8', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '14', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '15', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '16', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '21', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '22', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '26', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '27', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '28', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '31', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '33', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '34', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '35', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '37', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '38', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '40', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '41', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '43', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '44', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '48', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '50', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '51', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '53', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '54', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '55', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '57', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '59', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '61', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '64', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '65', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '66', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '67', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '69', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '71', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '74', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '78', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '80', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{ testId: '81', testType: 'AUTOMATIC', outcome: 'pass', results: [] },
{ testId: '83', testType: 'AUTOMATIC', outcome: 'na', results: [] },
{
testId: '85',
testType: 'AUTOMATIC',
outcome: 'fail',
results: [ [Object], [Object], [Object], [Object], [Object] ]
},
This output goes on for every test run. Expect a long list.
You could parse and process the test output in any way you wish either in the code of your test harness or via your own data analytics but it might be more useful to let the Level Access Platform do some of that lifting for you. Instead of just dumping the output to the console we can use the SDK to package up those results and push them to the platform.
- If you want, you can remove the console output lines from the previous step.
- Before the driver.quit() line in web_automation.js, add some code that'll create a scan session in the platform and store the findings in there.
// Create an object to send results to the Platform.
const levelAccessPlatformReportingService = Continuum.LevelAccessPlatformReportingService;
// Open a scan session with the Platform.
// We also give the name to our report here.
await levelAccessPlatformReportingService.openScanSession({
sessionName: 'Zero to Hero Demo'
});
// Grab the findings from the automated scan and upload them to the platform
try {
const assertions = Continuum.getAssertions();
await levelAccessPlatformReportingService.submit(assertions);
} finally {
await levelAccessPlatformReportingService.completeScanSession();
}
Note:
There is one gotcha here. Our example is interacting with and scanning duckduckgo.com and when outputting results to the console that works fine. Most clients won't have this domain in their list of allowed digital assets, so pushing results for this domain will probably fail. To fully complete this walkthrough, you'll need to modify the web_automation.js to use a digital asset that is allowed on your account. Ideally you would still do some manipulation of the page, but the approach will be the same whether you scan the page in its initial state or after having the Cucumber automation interact with it.
- Save the file, run it, and check the Level Access Platform, for the Organization, Workspace and Digital Asset configured in your continuum.conf.js.
We should now see a new entry, that is, the scan results for our demo session Zero to Hero:
High-level script overview: What your file should look like
Here’s what’s happened in the script we presented in this example:
| Step | Description |
| Test for assertions | The Level Access Platform accepts test results in the form of assertions. For Continuum to produce test results in this format, you must call the runAllTestsForAssertions() method. This will return an array of Assertion objects. |
| Get the reporting service | Submitting results to the Level Access Platform is done through a reporting service. You must retrieve an instance of the LevelAccessPlatformReportingService from Continuum by accessing the LevelAccessPlatformReportingService property. The returned reporting service instance allows you to open and complete scan sessions and submit the results. |
| Open a scan session | Before you submit any test results to the Level Access Platform, you must have an active scan session opened. You can open a new scan session by calling the openScanSession() method on the LevelAccessPlatformReportingService instance retrieved from Continuum. You must provide a name for your scan session. |
| Submit results | When you open a scan session, you can submit test results to the Level Access Platform. To do this, you can call the submit() method on the LevelAccessPlatformReportingService instance, retrieved from Continuum passing an array of Assertion objects. The supplied assertions will be posted to the Level Access Platform and stored as findings, for the URL the browser is currently at. The page title and screen dimensions are also automatically recorded and sent along with the assertions. |
| Complete the scan session | When you have finished testing you can complete your scan session by calling the completeScanSession() method on the LevelAccessPlatformReportingService instance retrieved from Continuum. |
If you followed each step in the example we provided, your file should look as follows:
const { Builder, By } = require('selenium-webdriver');
const {Continuum} = require('@continuum/continuum-javascript-professional');
// Define a function that automates a test.
async function web_automation() {
// Create a new web driver object to talk to chrome
let driver = await new Builder().forBrowser("chrome").build();
// Setup Continuum using the relative path of the continuum.conf.js file
await Continuum.setUp(driver, require('path').resolve(__dirname, "./continuum.conf.js"));
// .get tells the driver to make the web browser go to a website
await driver.get("https://www.duckduckgo.com");
// Test the current page for accessibility
await Continuum.runAllTestsForAssertions();
//Fill out the search form
// .findElement will locate an element using By.css
// .sendKeys will type to that field found
await driver.findElement(By.css("input[name='q']")).sendKeys("camping equipment");
// Find the submit button and click it (searches and redirects the page)
await driver.findElement(By.css("button[type='submit']")).click();
// Test the current page for accessibility
await Continuum.runAllTests();
// Pause for 10 seconds (10,000 ms), or else the window will close automatically.
// Not necessary, but nice to see what the browser is doing at the end.
await driver.sleep(10000);
// Create an object to send results to the Platform.
const levelAccessPlatformReportingService = Continuum.LevelAccessPlatformReportingService;
// Open a scan session with the Platform.
// We also give the name to our report here.
await levelAccessPlatformReportingService.openScanSession({
sessionName: 'Zero to Hero Demo'
});
// Grab the findings from the automated scan and upload them to the platform
try {
const assertions = Continuum.getAssertions();
await levelAccessPlatformReportingService.submit(assertions);
} finally {
await levelAccessPlatformReportingService.completeScanSession();
}
// Close the web browser driver
driver.quit()
}
// Output all the findings to the console
const console_assertions = Continuum.getAssertions();
console.log(console_assertions);
// Run the function above.
web_automation();You now have a complete working example, From Zero to Hero, of creating a web automation accessibility test using our Level Access Testing SDK to run Access Engine.
You can take what we have accomplished so far as a starting point and then mold it to fit into popular end-to-end testing frameworks. Proceed to SDK Primer Part 3: Testing framework guidance (Cucumber example).
Comments
0 comments
Please sign in to leave a comment.