@browserstack/accessibility-devtools
v1.5.0
Published
Command-line interface for BrowserStack Accessibility DevTools
Readme
Accessibility DevTools
Run accessibility checks on your React and HTML files
Usage
Step 1: Authentication
Pre-Requisites
- Sign up on http://browserstack.com
- Get your Username and Access Key by logging in to http://browserstack.com and going to Profile → Account & Profile → My Profile → Authentication & Security
For local execution
Set up the two environment variables BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY
- For Zsh, add in
~/.zshrc - For Bash, add in
~/.bashrcor~/.bash_profile - For Fish Shell, add in
~/.config/fish/config.fish
For CI/CD
Save the username and access key in the CI/CD secrets and inject into the build.
Step 2: Run your tests
Via CLI
Run the linter manually from your terminal, or integrate it into Git pre-commit hooks and build scripts.
npx @browserstack/accessibility-devtools -i src/**/*.tsxCLI Options
`--version`: Show version number
`--include` or `-i`: Glob pattern(s) for files to lint
`--exclude` or `-e`: Glob pattern(s) for files to exclude from linting
`--username` or `-u`: BrowserStack username (if not provided, taken from BROWSERSTACK_USERNAME env variable)
`--access-key` or `-k`: BrowserStack access key (if not provided, taken from BROWSERSTACK_ACCESS_KEY env variable)
`--non-strict` or `-n`: Run in non-strict mode (only print violations, do not exit with non-success code)
`--scope <mode>`: Limit violations to lines touched by the diff (choices: `diff`, `all`; default: `all`). See `--base` and `--git-root` for the related CI-mode flags. Currently git only — non-git VCSes (SVN, Mercurial, Perforce, Bazaar, Darcs) get a friendly error pointing at this constraint.
`--base <ref>`: Base ref for diff comparison (e.g. `origin/main`). Required only with `--scope=diff` in CI mode (when comparing against a branch tip rather than your local staging area). Three-dot semantics (`<base>...HEAD`) — equivalent to `git diff $(git merge-base <base> HEAD) HEAD`.
`--git-root <path>`: Git work-tree root (defaults to cwd). Required when CI mounts only a subdirectory (no `.git` walking up from cwd), or for `git archive`-extracted artifacts. Only consulted with `--scope=diff`.
`--help`: Show helpExit Codes:
0 - no issues
1 - open accessibility issues
2 - BrowserStack connection issues
CI setup for --scope=diff
--scope=diff --base=<ref> requires full git history so git diff <base>...HEAD can resolve. CI providers default to shallow clones; you'll need to opt into full history.
GitHub Actions
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history; required for --scope=diff --base=origin/main
- run: npx @browserstack/accessibility-devtools -i 'src/**/*.tsx' --scope=diff --base=origin/mainGitLab CI
variables:
GIT_DEPTH: '0' # full history; required for --scope=diff --base=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
a11y:
script:
- npx @browserstack/accessibility-devtools -i 'src/**/*.tsx' --scope=diff --base=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAMEJenkins, Bitbucket Pipelines, Azure Pipelines
See the docs page for the equivalent shallow-clone-disable recipe per provider.
Troubleshooting --scope=diff
| Error message | What happened | Fix |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| --scope=diff requires full git history but this repository is a shallow clone. | CI checked out a shallow clone (default for most providers). | See the CI setup section above for fetch-depth: 0 / GIT_DEPTH: "0" etc. |
| --scope=diff currently supports git only. Detected <VCS> in this directory... | You ran --scope=diff from a directory containing .svn / .hg / .p4config / .bzr / _darcs. Diff scoping is git-only in v1. | Use --scope=all (the default), or skip the flag entirely. Non-git VCS support is tracked for future work. |
| --scope=diff found no staged changes. Unstaged changes (N file(s)) are not part of pre-commit linting... | You ran --scope=diff locally with unstaged work but nothing staged. | git add the files you intend to commit, then re-run. Or use --base=<ref> for branch-comparison linting. |
| --scope=diff found no uncommitted changes to lint. | Working tree is clean — nothing to diff against. | Make a change, or use --base=<ref> to compare against a branch. |
| [deva11y] note: --scope=diff touched N file(s) but none overlap with --include/--exclude. | Your touched-files set didn't intersect the lint targets. Common cause: --git-root pointing at a different repo than the one containing your lint targets. | Verify --git-root (if supplied), or widen --include to cover the touched files. |
| --base only applies with --scope=diff | You passed --base=<ref> without --scope=diff (or with --scope=all). | Add --scope=diff or remove --base. |
Via Node.js
Install the BrowserStack Accessibility DevTools via npm
npm install @browserstack/accessibility-devtools --save-devUse the API for custom build scripts (like Gulp/Node.js runners etc.)
export interface AccessibilityDevToolsOptions {
// List of glob patterns to include in the linting process.
include: string[];
// List of glob patterns to exclude from the linting process.
exclude?: string[];
// BrowserStack credentials
browserstackUsername: string;
browserstackAccessKey: string;
// Whether to run in non-strict mode, default: false
nonStrict?: boolean;
// Pre-resolved touched-lines map for --scope=diff. Keys MUST be
// `fs.realpathSync.native(path.resolve(gitRoot, repoRelativePath))`.
// `null`/`undefined` skips the line-level filter; an empty Map runs the
// filter and produces an empty report. In-process only — not safely
// serializable across worker/RPC boundaries that lose Map/Set semantics.
touchedLines?: Map<string, Set<number>> | null;
}
enum RunStatus {
SUCCESS = 0,
FAILURE = 1,
ERROR = 2,
}
export interface LintResult {
exitCode: RunStatus;
report: LintReport | null;
}
export default function runA11yDevtools(options: AccessibilityDevToolsOptions): Promise<LintResult>;Sample code snippet:
import runA11yDevtools from '@browserstack/accessibility-devtools';
const { exitCode, report } = await runA11yDevtools({
include: ['src/**/*.jsx'],
exclude: [],
browserstackUsername: 'your_username',
browserstackAccessKey: 'your_access_key',
});API Parameters
| Property | Type | Required | Description |
| :---------------------- | :--------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| include | string[] | Yes | Glob pattern(s) for files to lint. |
| browserstackUsername | string | Yes | Your BrowserStack account username. |
| browserstackAccessKey | string | Yes | Your BrowserStack account access key. |
| exclude | string[] | No | Glob pattern(s) to ignore. |
| nonStrict | boolean | No | Run in non-strict mode (only print violations, do not exit with non-success code). |
| touchedLines | Map<string, Set<number>> \| null | No | Pre-resolved touched-lines map for --scope=diff. The CLI binary constructs this from git; library callers (browserstack-binary proxy, JetBrains plugin) may construct it themselves. Keys MUST be fs.realpathSync.native(path.resolve(gitRoot, repoRelativePath)) — see the inline type JSDoc for the full recipe. |
