Skip to content

Commit

Permalink
Add parameter for Axe context
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuth committed Jul 25, 2024
1 parent fd349b3 commit 737c419
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 41 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- [new] Add parameter for Axe `context` [#98](https://github.com/chanzuckerberg/axe-storybook-testing/pull/98)

## 8.1.0

- [new] Add `--port` option [#97](https://github.com/chanzuckerberg/axe-storybook-testing/pull/97)
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ If there are any violations, information about them will be printed, and the com
- [disabledRules](#disabledrules)
- [mode](#mode)
- [runOptions](#runoptions)
- [context](#context)
- [config](#config)
- [skip](#skip)
- [timeout](#timeout)
Expand Down Expand Up @@ -167,6 +168,22 @@ export const SomeStory = {
}
```
### context
[Axe context](https://www.deque.com/axe/core-documentation/api-documentation/#context-parameter), which is passed to `axe.run`. Useful for including or excluding elements from the tests.
```jsx
export const SomeStory = {
parameters: {
axe: {
context: {
exclude: '.foo',
},
}
}
}
```
### config
Axe configuration, which is passed to [axe.configure](https://www.deque.com/axe/core-documentation/api-documentation/#api-name-axeconfigure).
Expand Down
23 changes: 23 additions & 0 deletions demo/src/advanced.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,26 @@ export const branding = {
},
},
};

// Test out passing context to `axe.run`.
export const multipleParts = {
render: () => (
<div>
<div id="a">
<button style={{backgroundColor: 'red', color: 'hotpink'}}>
hello A
</button>
</div>
<div id="b">
<button style={{backgroundColor: 'red', color: 'hotpink'}}>
hello B
</button>
</div>
</div>
),
parameters: {
axe: {
context: '#a',
},
},
};
12 changes: 11 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type {RunOptions, Spec} from 'axe-core';
import type {
RunOptions,
SerialContextObject,
SerialFrameSelector,
Spec,
} from 'axe-core';

export declare type AxeParams = {
/**
Expand Down Expand Up @@ -26,6 +31,11 @@ export declare type AxeParams = {
* @see https://www.deque.com/axe/core-documentation/api-documentation/#options-parameter
*/
runOptions?: RunOptions;
/**
* Context passed to `axe.run`.
* @see https://www.deque.com/axe/core-documentation/api-documentation/#context-parameter
*/
context?: SerialFrameSelector | SerialFrameSelector[] | SerialContextObject;
/**
* Config passed to `axe.configure`.
*/
Expand Down
29 changes: 29 additions & 0 deletions src/ProcessedStory.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type {RunOptions, Spec} from 'axe-core';
import {z as zod} from 'zod';
import type {Context} from './browser/AxePage';
import type {StorybookStory} from './browser/StorybookPage';

type Params = {
disabledRules: string[];
mode: 'off' | 'warn' | 'error';
runOptions?: RunOptions;
context?: Context;
config?: Spec;
skip: boolean;
timeout: number;
Expand Down Expand Up @@ -42,6 +44,9 @@ export default class ProcessedStory {
rawStory.parameters?.axe?.runOptions,
rawStory,
),
context: normalizeContext(rawStory.parameters?.axe?.context, rawStory) as
| Context
| undefined,
config: normalizeConfig(rawStory.parameters?.axe?.config, rawStory),
};
}
Expand Down Expand Up @@ -75,6 +80,14 @@ export default class ProcessedStory {
return this.parameters.runOptions;
}

/**
* Context passed to `axe.run`.
* @see https://www.deque.com/axe/core-documentation/api-documentation/#context-parameter
*/
get context() {
return this.parameters.context;
}

/**
* All optional config used to configure axe-core. Passed to `axe.configure`.
* @see https://www.deque.com/axe/core-documentation/api-documentation/#api-name-axeconfigure
Expand Down Expand Up @@ -138,6 +151,14 @@ const runOptionsSchema = zod.optional(
}),
);

const contextSchema = zod
.union([
zod.string(),
zod.array(zod.string()),
zod.record(zod.string(), zod.any()),
])
.optional();

const configSchema = zod.object({}).passthrough().optional();

function normalizeSkip(skip: unknown, rawStory: StorybookStory) {
Expand Down Expand Up @@ -175,6 +196,14 @@ function normalizeRunOptions(runOptions: unknown, rawStory: StorybookStory) {
);
}

function normalizeContext(config: unknown, rawStory: StorybookStory) {
return parseWithFriendlyError(
() => contextSchema.parse(config),
rawStory,
'context',
);
}

function normalizeConfig(config: unknown, rawStory: StorybookStory) {
return parseWithFriendlyError(
() => configSchema.parse(config),
Expand Down
1 change: 1 addition & 0 deletions src/Result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default class Result {
page,
disabledRules,
story.runOptions,
story.context,
story.config,
);
return new Result(axeResults.violations);
Expand Down
24 changes: 20 additions & 4 deletions src/browser/AxePage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import type {AxeResults, RuleObject, RunOptions, Spec} from 'axe-core';
import type {
AxeResults,
SerialContextObject,
SerialFrameSelector,
RuleObject,
RunOptions,
Spec,
} from 'axe-core';
import type {Page} from 'playwright';

export type Context =
| SerialFrameSelector
| SerialFrameSelector[]
| SerialContextObject;

/**
* Prepare a page for running axe on it.
*/
Expand All @@ -17,20 +29,24 @@ export function analyze(
page: Page,
disabledRules: string[] = [],
runOptions: RunOptions = {},
context?: Context,
config?: Spec,
): Promise<AxeResults> {
return page.evaluate(runAxe, {
options: getRunOptions(runOptions, disabledRules),
config,
context,
});
}

function runAxe({
options,
config,
context,
options,
}: {
options: RunOptions;
config?: Spec;
context?: Context;
options: RunOptions;
}): Promise<AxeResults> {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore This function executes in a browser context.
Expand All @@ -49,7 +65,7 @@ function runAxe({

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore This function executes in a browser context.
return window.axe.run(document, options);
return window.axe.run(context || document, options);
});
}

Expand Down
Loading

0 comments on commit 737c419

Please sign in to comment.