Skip to content

Commit

Permalink
v1.0.0: Clean up API/file naming, add README (#25)
Browse files Browse the repository at this point in the history
#### Description of changes

* Bumps package.json to version 1.0.0
* Updates name/types of the exported API
* Documents usage in README
* Cleans up a few orphaned types (`ruleresults.ts`) and nonstandard file names (`/sarif/*.ts`)
* Removes options parameter until we finalize which properties we want to offer (none of the old options map directly to first class properties in the new sarif format; probably want to reconsider that before making them part of our API surface).

#### Pull request checklist

- [x] Addresses an existing issue: Prepares for initial package release #21
- [x] **n/a** Added relevant unit test for your changes. (`npm run test`)
- [x] Verified code coverage for the changes made.
  • Loading branch information
dbjorge authored Apr 10, 2019
1 parent ae0a954 commit 8d0c9b1
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 170 deletions.
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,35 @@ Licensed under the MIT License.

# axe-sarif-converter

**An [axe-core](https://github.com/dequelabs/axe-core) reporter that outputs axe scan results in [SARIF format](http://sarifweb.azurewebsites.net/).**
Convert [axe-core](https://github.com/dequelabs/axe-core) accessibility scan results to the [SARIF format](http://sarifweb.azurewebsites.net/).

Use this with the [Sarif Viewer Build Tab Azure DevOps Extension](https://marketplace.visualstudio.com/items?itemName=sariftools.sarif-viewer-build-tab) to visualize accessibility scan results in the build results of an [Azure Pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/) build.

## Usage

Before using axe-sarif-converter, you will need to run an [axe](https://github.com/dequelabs/axe-core) accessibility scan to produce some axe results to convert. Typically, you would do this by using an axe integration library for your favorite browser automation tool ([axe-puppeteer](https://github.com/dequelabs/axe-puppeteer), [axe-webdriverjs](https://github.com/dequelabs/axe-webdriverjs), [cypress-axe](https://github.com/avanslaars/cypress-axe)).

axe-sarif-converter exports a single function, named `convertAxeToSarif`. Use it like this:

```ts
import { convertAxeToSarif, SarifLog } from 'axe-sarif-converter';

test('my accessibility test', async () => {
// This example uses axe-puppeteer, but you can use any axe-based library
// that outputs axe scan results in the default axe output format
const testPage: Puppeteer.Page = /* ... set up your test page ... */;
const axeResults: Axe.AxeResults = await new AxePuppeteer(testPage).analyze();

// Perform the conversion
const sarifResults: SarifLog = convertAxeToSarif(axeResults);

// Output a SARIF file, perhaps for use with a Sarif Viewer tool
await fs.promises.writeFile(
'./test-results/my-accessibility-test.sarif',
JSON.stringify(sarifResults),
{ encoding: 'utf8' });
}
```
## Contributing
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "axe-sarif-converter",
"version": "0.0.1",
"description": "An axe-core reporter that outputs axe scan results in SARIF format (http://sarifweb.azurewebsites.net/)",
"version": "1.0.0",
"description": "Convert axe-core accessibility scan results to the SARIF format",
"main": "dist/index.js",
"types": "dist/index.d.js",
"files": [
Expand Down
20 changes: 20 additions & 0 deletions src/decorated-axe-results.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as Axe from 'axe-core';
import { WCAG } from './wcag';

export interface AxeResultDecorations {
WCAG?: WCAG[];
}

export type DecoratedAxeResult = Axe.Result & AxeResultDecorations;

export interface DecoratedAxeResults {
passes: DecoratedAxeResult[];
violations: DecoratedAxeResult[];
inapplicable: DecoratedAxeResult[];
incomplete: DecoratedAxeResult[];
timestamp: string;
targetPageUrl: string;
targetPageTitle: string;
}
12 changes: 6 additions & 6 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
TestRunner,
} from 'axe-core';
import * as fs from 'fs';
import { axeToSarif } from './index';
import { SarifLog } from './sarif/sarifLog';
import { Run } from './sarif/sarifv2';
import { convertAxeToSarif } from './index';
import { Run } from './sarif/sarif-2.0.0';
import { SarifLog } from './sarif/sarif-log';

describe('axe-sarf-converter integration test', () => {
it('axe-sarif-converter returns a valid sarif with blank results array in run array', () => {
Expand Down Expand Up @@ -64,8 +64,8 @@ describe('axe-sarf-converter integration test', () => {
] as Run[],
};

expect(axeToSarif(axeResultStub)).toBeDefined();
expect(axeToSarif(axeResultStub)).toEqual(expected);
expect(convertAxeToSarif(axeResultStub)).toBeDefined();
expect(convertAxeToSarif(axeResultStub)).toEqual(expected);
});
});

Expand All @@ -76,6 +76,6 @@ describe('axeToSarifConverter use generated AxeResults object', () => {
'utf8',
);
const axeResultStub: AxeResults = JSON.parse(axeJSON) as AxeResults;
expect(axeToSarif(axeResultStub)).toMatchSnapshot();
expect(convertAxeToSarif(axeResultStub)).toMatchSnapshot();
});
});
20 changes: 4 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as Axe from 'axe-core';
import { ConverterOptions } from './converter-options';
import { ResultDecorator } from './result-decorator';
import { SarifConverter } from './sarif-converter';
import { SarifLog } from './sarif/sarifLog';
import { SarifLog } from './sarif/sarif-log';
import { rulesWCAGConfiguration } from './wcag-mappings';

export { ConverterOptions } from './converter-options';

export function axeToSarif(
axeResults: Axe.AxeResults,
options?: ConverterOptions,
): SarifLog {
options = options ? options : {};

export function convertAxeToSarif(axeResults: Axe.AxeResults): SarifLog {
const resultDecorator = new ResultDecorator(rulesWCAGConfiguration);
const decoratedAxeResults = resultDecorator.decorateResults(axeResults);

const sarifConverter = new SarifConverter();

// AxeResults -> ScannerResults
const scannerResults = resultDecorator.decorateResults(axeResults);

// ScannerResults -> ISarifLog
return sarifConverter.convert(scannerResults, options);
return sarifConverter.convert(decoratedAxeResults, {});
}
14 changes: 7 additions & 7 deletions src/result-decorator.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { AxeResults, Result } from 'axe-core';
import { DecoratedAxeResults } from './decorated-axe-results';
import { DictionaryStringTo } from './dictionary-types';
import { ResultDecorator } from './result-decorator';
import { ScannerResults } from './ruleresults';
import { WCAG } from './wcag';

describe('Result Decorator', () => {
Expand All @@ -25,11 +25,11 @@ describe('Result Decorator', () => {

const wcagInfo: DictionaryStringTo<WCAG[]> = {};
const resultDecorator = new ResultDecorator(wcagInfo);
const decoratedResult: ScannerResults = resultDecorator.decorateResults(
const decoratedResults: DecoratedAxeResults = resultDecorator.decorateResults(
resultStub,
);
expect(decoratedResult.violations).toEqual([]);
expect(resultDecorator.decorateResults(resultStub)).toMatchSnapshot();
expect(decoratedResults.violations).toEqual([]);
expect(decoratedResults).toMatchSnapshot();
});

it('result decorator contains WCAG information that is provided as dependency', () => {
Expand Down Expand Up @@ -73,10 +73,10 @@ describe('Result Decorator', () => {
},
];

const decoratedResult: ScannerResults = resultDecorator.decorateResults(
const decoratedResults: DecoratedAxeResults = resultDecorator.decorateResults(
resultStub,
);
expect(decoratedResult.violations).toEqual(expectedViolation);
expect(decoratedResult.violations[0].WCAG).toEqual([{ text: 'test' }]);
expect(decoratedResults.violations).toEqual(expectedViolation);
expect(decoratedResults.violations[0].WCAG).toEqual([{ text: 'test' }]);
});
});
13 changes: 8 additions & 5 deletions src/result-decorator.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as Axe from 'axe-core';
import {
DecoratedAxeResult,
DecoratedAxeResults,
} from './decorated-axe-results';
import { DictionaryStringTo } from './dictionary-types';
import { AxeCoreRuleResult, AxeRule, ScannerResults } from './ruleresults';
import { WCAG } from './wcag';

export class ResultDecorator {
constructor(private wcagConfiguration: DictionaryStringTo<WCAG[]>) {}

public decorateResults(results: Axe.AxeResults): ScannerResults {
public decorateResults(results: Axe.AxeResults): DecoratedAxeResults {
return {
passes: this.decorateAxeRuleResults(results.passes),
violations: this.decorateAxeRuleResults(results.violations),
Expand All @@ -21,9 +24,9 @@ export class ResultDecorator {
}

private decorateAxeRuleResults(
ruleResults: AxeRule[],
): AxeCoreRuleResult[] {
return ruleResults.map<AxeCoreRuleResult>((result: AxeRule) => {
ruleResults: Axe.Result[],
): DecoratedAxeResult[] {
return ruleResults.map<DecoratedAxeResult>((result: Axe.Result) => {
return { ...result, WCAG: this.getRelatedWCAGByRuleId(result.id) };
});
}
Expand Down
102 changes: 0 additions & 102 deletions src/ruleresults.ts

This file was deleted.

Loading

0 comments on commit 8d0c9b1

Please sign in to comment.