From 4276db6df9bca5ed65a3e4c354675686d7ae2688 Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Tue, 9 Aug 2022 14:15:43 +0200 Subject: [PATCH 01/14] Allow matcher to accept results object --- README.md | 13 +++++++++ src/axe/index.ts | 27 ++++++++++++++++++ src/index.ts | 1 + src/matchers/toBeAccessible/index.ts | 42 ++++++++++------------------ src/types/index.ts | 6 ++++ src/utils/axe.ts | 2 +- 6 files changed, 63 insertions(+), 28 deletions(-) create mode 100644 src/axe/index.ts create mode 100644 src/types/index.ts diff --git a/README.md b/README.md index 5324b82..d70d0a1 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,19 @@ Or pass a locator to test part of the page: await expect(page.locator('#my-element')).toBeAccessible() ``` +You can also pass an [Axe results +object](https://www.deque.com/axe/core-documentation/api-documentation/#results-object) +to the matcher: + +```js +import { runAxe } from 'expect-axe-playwright' + +test('should be accessible', async ({ page }) => { + const { results } = runAxe(page) + await expect(results).toBeAccessible() +}); +``` + #### Axe run options You can configure options that should be passed to aXe at the project or diff --git a/src/axe/index.ts b/src/axe/index.ts new file mode 100644 index 0000000..ac8ba3a --- /dev/null +++ b/src/axe/index.ts @@ -0,0 +1,27 @@ +import type { AxeResults, RunOptions } from 'axe-core' +import test from '@playwright/test' +import merge from 'merge-deep' +import { injectAxe, runAxeAfterInject } from '../utils/axe' +import { Handle, resolveLocator } from '../utils/matcher' +import { poll } from '../utils/poll' + +export async function runAxe( + handle: Handle, + { timeout, ...options }: { timeout: number | undefined } & RunOptions +): Promise<{ + ok: boolean + results: AxeResults +}> { + const info = test.info() + const opts = merge(info.project.use.axeOptions, options) + const locator = resolveLocator(handle) + await injectAxe(locator) + return await poll(locator, timeout, async () => { + const results = await runAxeAfterInject(locator, opts) + + return { + ok: !results.violations.length, + results, + } + }) +} diff --git a/src/index.ts b/src/index.ts index 1aa20ef..c264555 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,3 @@ import matchers from './matchers' +export { runAxe } from './axe' export default matchers diff --git a/src/matchers/toBeAccessible/index.ts b/src/matchers/toBeAccessible/index.ts index ac743cb..2140c8c 100644 --- a/src/matchers/toBeAccessible/index.ts +++ b/src/matchers/toBeAccessible/index.ts @@ -1,49 +1,37 @@ import test from '@playwright/test' import type { MatcherState } from '@playwright/test/types/expect-types' -import type { Result, RunOptions } from 'axe-core' +import type { AxeResults, Result } from 'axe-core' +import type { MatcherOptions } from '../../types' +import type { Handle } from '../../utils/matcher' import createHTMLReport from 'axe-reporter-html' -import merge from 'merge-deep' import { attach } from '../../utils/attachments' -import { injectAxe, runAxe } from '../../utils/axe' -import { Handle, resolveLocator } from '../../utils/matcher' -import { poll } from '../../utils/poll' +import { runAxe } from '../../axe' const summarize = (violations: Result[]) => violations .map((violation) => `${violation.id}(${violation.nodes.length})`) .join(', ') -interface MatcherOptions extends RunOptions { - timeout?: number - filename?: string -} - export async function toBeAccessible( this: MatcherState, - handle: Handle, - { timeout, ...options }: MatcherOptions = {} + handleOrResults: Handle | AxeResults, + { timeout, filename = 'axe-report.html', ...options }: MatcherOptions = {} ) { try { - const locator = resolveLocator(handle) - await injectAxe(locator) - - const info = test.info() - const opts = merge(info.project.use.axeOptions, options) - - const { ok, results } = await poll(locator, timeout, async () => { - const results = await runAxe(locator, opts) - - return { - ok: !results.violations.length, - results, - } - }) + let ok: boolean + let results: AxeResults + if ((handleOrResults as AxeResults).violations) { + results = handleOrResults as AxeResults + ok = !!results.violations.length + } else { + ({ ok, results } = await runAxe(handleOrResults as Handle, { timeout, ...options })) + } // If there are violations, attach an HTML report to the test for additional // visibility into the issue. if (!ok) { const html = await createHTMLReport(results) - const filename = opts.filename || 'axe-report.html' + const info = test.info() await attach(info, filename, html) } diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..f75f54b --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,6 @@ +import type { RunOptions } from 'axe-core' + +export interface MatcherOptions extends RunOptions { + timeout?: number + filename?: string +} diff --git a/src/utils/axe.ts b/src/utils/axe.ts index cf78390..a4b60f9 100644 --- a/src/utils/axe.ts +++ b/src/utils/axe.ts @@ -30,7 +30,7 @@ export async function injectAxe(locator: Locator) { * Runs axe on an element handle. The script must already be injected * using `injectAxe`. */ -export function runAxe(locator: Locator, options: RunOptions = {}) { +export function runAxeAfterInject(locator: Locator, options: RunOptions = {}) { return locator.evaluate( (el, options) => window.axe.run(el, options), options From 5a819e22119c5e907e3a0dfc1a42aa061e87f054 Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Wed, 7 Sep 2022 21:47:37 -0500 Subject: [PATCH 02/14] requested changes from review --- README.md | 2 +- src/axe/index.ts | 27 ----------------- src/index.ts | 2 +- src/matchers/toBeAccessible/index.spec.ts | 12 ++++++++ src/matchers/toBeAccessible/index.ts | 36 +++++++++++++++-------- src/utils/axe.ts | 2 +- src/utils/{matcher.ts => locator.ts} | 0 src/waitForAxeResults.spec.ts | 19 ++++++++++++ src/waitForAxeResults.ts | 33 +++++++++++++++++++++ 9 files changed, 90 insertions(+), 43 deletions(-) delete mode 100644 src/axe/index.ts rename src/utils/{matcher.ts => locator.ts} (100%) create mode 100644 src/waitForAxeResults.spec.ts create mode 100644 src/waitForAxeResults.ts diff --git a/README.md b/README.md index d70d0a1..5205205 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ to the matcher: import { runAxe } from 'expect-axe-playwright' test('should be accessible', async ({ page }) => { - const { results } = runAxe(page) + const { results } = await waitForAxeResults(page) await expect(results).toBeAccessible() }); ``` diff --git a/src/axe/index.ts b/src/axe/index.ts deleted file mode 100644 index ac8ba3a..0000000 --- a/src/axe/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { AxeResults, RunOptions } from 'axe-core' -import test from '@playwright/test' -import merge from 'merge-deep' -import { injectAxe, runAxeAfterInject } from '../utils/axe' -import { Handle, resolveLocator } from '../utils/matcher' -import { poll } from '../utils/poll' - -export async function runAxe( - handle: Handle, - { timeout, ...options }: { timeout: number | undefined } & RunOptions -): Promise<{ - ok: boolean - results: AxeResults -}> { - const info = test.info() - const opts = merge(info.project.use.axeOptions, options) - const locator = resolveLocator(handle) - await injectAxe(locator) - return await poll(locator, timeout, async () => { - const results = await runAxeAfterInject(locator, opts) - - return { - ok: !results.violations.length, - results, - } - }) -} diff --git a/src/index.ts b/src/index.ts index c264555..b02ef04 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ import matchers from './matchers' -export { runAxe } from './axe' +export { waitForAxeResults } from './waitForAxeResults' export default matchers diff --git a/src/matchers/toBeAccessible/index.spec.ts b/src/matchers/toBeAccessible/index.spec.ts index e8def71..8ba0fbf 100644 --- a/src/matchers/toBeAccessible/index.spec.ts +++ b/src/matchers/toBeAccessible/index.spec.ts @@ -129,4 +129,16 @@ test.describe.parallel('toBeAccessible', () => { .catch(() => Promise.resolve()) expect(attachmentExists(filename)).toBe(true) }) + + test.describe('with Axe results object', async () => { + test('positive', async () => { + const results = { violations: [] } + await expect(results).toBeAccessible() + }) + + test('negative', async () => { + const results = { violations: [{ id: 'foo', nodes: [] }] } + await expect(results).not.toBeAccessible() + }) + }) }) diff --git a/src/matchers/toBeAccessible/index.ts b/src/matchers/toBeAccessible/index.ts index 2140c8c..418cd69 100644 --- a/src/matchers/toBeAccessible/index.ts +++ b/src/matchers/toBeAccessible/index.ts @@ -2,36 +2,46 @@ import test from '@playwright/test' import type { MatcherState } from '@playwright/test/types/expect-types' import type { AxeResults, Result } from 'axe-core' import type { MatcherOptions } from '../../types' -import type { Handle } from '../../utils/matcher' +import type { Handle } from '../../utils/locator' import createHTMLReport from 'axe-reporter-html' +import merge from 'merge-deep' import { attach } from '../../utils/attachments' -import { runAxe } from '../../axe' +import { waitForAxeResults } from '../../waitForAxeResults' const summarize = (violations: Result[]) => violations .map((violation) => `${violation.id}(${violation.nodes.length})`) .join(', ') +async function getResults(obj: Handle | AxeResults, options: MatcherOptions) { + if ((obj as AxeResults).violations) { + const results = obj as AxeResults + return { + results, + ok: !results.violations.length + } + } else { + const handle = obj as Handle + return waitForAxeResults(handle, options); + } +} + export async function toBeAccessible( this: MatcherState, - handleOrResults: Handle | AxeResults, - { timeout, filename = 'axe-report.html', ...options }: MatcherOptions = {} + obj: Handle | AxeResults, + options: MatcherOptions = {} ) { try { - let ok: boolean - let results: AxeResults - if ((handleOrResults as AxeResults).violations) { - results = handleOrResults as AxeResults - ok = !!results.violations.length - } else { - ({ ok, results } = await runAxe(handleOrResults as Handle, { timeout, ...options })) - } + const { results, ok } = await getResults(obj, options) + + const info = test.info() + const opts = merge(info.project.use.axeOptions, options) // If there are violations, attach an HTML report to the test for additional // visibility into the issue. if (!ok) { const html = await createHTMLReport(results) - const info = test.info() + const filename = opts.filename || 'axe-report.html' await attach(info, filename, html) } diff --git a/src/utils/axe.ts b/src/utils/axe.ts index a4b60f9..cf78390 100644 --- a/src/utils/axe.ts +++ b/src/utils/axe.ts @@ -30,7 +30,7 @@ export async function injectAxe(locator: Locator) { * Runs axe on an element handle. The script must already be injected * using `injectAxe`. */ -export function runAxeAfterInject(locator: Locator, options: RunOptions = {}) { +export function runAxe(locator: Locator, options: RunOptions = {}) { return locator.evaluate( (el, options) => window.axe.run(el, options), options diff --git a/src/utils/matcher.ts b/src/utils/locator.ts similarity index 100% rename from src/utils/matcher.ts rename to src/utils/locator.ts diff --git a/src/waitForAxeResults.spec.ts b/src/waitForAxeResults.spec.ts new file mode 100644 index 0000000..57ed209 --- /dev/null +++ b/src/waitForAxeResults.spec.ts @@ -0,0 +1,19 @@ +import { expect, test } from "@playwright/test" +import { readFile } from "./utils/file" +import { waitForAxeResults } from './waitForAxeResults' + +test.describe("waitForAxeResults", () => { + test("should be ok for page with no axe violations", async ({ page }) => { + const content = await readFile("accessible.html") + await page.setContent(content) + const { ok } = await waitForAxeResults(page) + await expect(ok).toBeTruthy() + }) + + test("should not be ok for page with axe violations", async ({ page }) => { + const content = await readFile("inaccessible.html"); + await page.setContent(content); + const { ok } = await waitForAxeResults(page) + await expect(ok).toBeFalsy() + }) +}) diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts new file mode 100644 index 0000000..b21d8b7 --- /dev/null +++ b/src/waitForAxeResults.ts @@ -0,0 +1,33 @@ +import test from "@playwright/test"; +import type { AxeResults, RunOptions } from "axe-core"; +import { Handle, resolveLocator } from "./utils/locator"; +import merge from "merge-deep"; +import { poll } from "./utils/poll"; +import { injectAxe, runAxe } from "./utils/axe"; + +/** + * Injects axe onto page, waits for the page to be ready, then runs axe against + * the provided element handle (which could be the entire page). + */ +export async function waitForAxeResults( + handle: Handle, + { timeout, ...options }: { timeout?: number } & RunOptions = {} +): Promise<{ + ok: boolean; + results: AxeResults; +}> { + const info = test.info(); + const opts = merge(info.project.use.axeOptions, options); + const locator = resolveLocator(handle); + await injectAxe(locator); + return poll(locator, timeout, async () => { + const results = await runAxe(locator, opts); + + return { + ok: !results.violations.length, + results, + }; + }); +} + +export default waitForAxeResults From becb144c75921c8603e5191201289d48dad59abf Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Wed, 7 Sep 2022 21:49:57 -0500 Subject: [PATCH 03/14] oops semicolons --- src/matchers/toBeAccessible/index.ts | 2 +- src/waitForAxeResults.spec.ts | 4 ++-- src/waitForAxeResults.ts | 30 ++++++++++++++-------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/matchers/toBeAccessible/index.ts b/src/matchers/toBeAccessible/index.ts index 418cd69..3cc5ede 100644 --- a/src/matchers/toBeAccessible/index.ts +++ b/src/matchers/toBeAccessible/index.ts @@ -22,7 +22,7 @@ async function getResults(obj: Handle | AxeResults, options: MatcherOptions) { } } else { const handle = obj as Handle - return waitForAxeResults(handle, options); + return waitForAxeResults(handle, options) } } diff --git a/src/waitForAxeResults.spec.ts b/src/waitForAxeResults.spec.ts index 57ed209..12bba2f 100644 --- a/src/waitForAxeResults.spec.ts +++ b/src/waitForAxeResults.spec.ts @@ -11,8 +11,8 @@ test.describe("waitForAxeResults", () => { }) test("should not be ok for page with axe violations", async ({ page }) => { - const content = await readFile("inaccessible.html"); - await page.setContent(content); + const content = await readFile("inaccessible.html") + await page.setContent(content) const { ok } = await waitForAxeResults(page) await expect(ok).toBeFalsy() }) diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts index b21d8b7..d9fe012 100644 --- a/src/waitForAxeResults.ts +++ b/src/waitForAxeResults.ts @@ -1,9 +1,9 @@ -import test from "@playwright/test"; -import type { AxeResults, RunOptions } from "axe-core"; -import { Handle, resolveLocator } from "./utils/locator"; -import merge from "merge-deep"; -import { poll } from "./utils/poll"; -import { injectAxe, runAxe } from "./utils/axe"; +import test from "@playwright/test" +import type { AxeResults, RunOptions } from "axe-core" +import { Handle, resolveLocator } from "./utils/locator" +import merge from "merge-deep" +import { poll } from "./utils/poll" +import { injectAxe, runAxe } from "./utils/axe" /** * Injects axe onto page, waits for the page to be ready, then runs axe against @@ -13,21 +13,21 @@ export async function waitForAxeResults( handle: Handle, { timeout, ...options }: { timeout?: number } & RunOptions = {} ): Promise<{ - ok: boolean; - results: AxeResults; + ok: boolean + results: AxeResults }> { - const info = test.info(); - const opts = merge(info.project.use.axeOptions, options); - const locator = resolveLocator(handle); - await injectAxe(locator); + const info = test.info() + const opts = merge(info.project.use.axeOptions, options) + const locator = resolveLocator(handle) + await injectAxe(locator) return poll(locator, timeout, async () => { - const results = await runAxe(locator, opts); + const results = await runAxe(locator, opts) return { ok: !results.violations.length, results, - }; - }); + } + }) } export default waitForAxeResults From 88908aac1e01343ee968e339804b56cad45d147c Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Wed, 7 Sep 2022 21:50:51 -0500 Subject: [PATCH 04/14] fix readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5205205..6cc1b59 100644 --- a/README.md +++ b/README.md @@ -78,12 +78,12 @@ object](https://www.deque.com/axe/core-documentation/api-documentation/#results- to the matcher: ```js -import { runAxe } from 'expect-axe-playwright' +import { waitForAxeResults } from 'expect-axe-playwright' test('should be accessible', async ({ page }) => { const { results } = await waitForAxeResults(page) await expect(results).toBeAccessible() -}); +}) ``` #### Axe run options From d3c05f7000f88f616114d7d4a3900fb636ae80b3 Mon Sep 17 00:00:00 2001 From: gabalafou Date: Thu, 8 Sep 2022 13:37:19 -0500 Subject: [PATCH 05/14] Apply suggestions from code review Co-authored-by: Mark Skelton --- src/matchers/toBeAccessible/index.ts | 3 +-- src/waitForAxeResults.ts | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/matchers/toBeAccessible/index.ts b/src/matchers/toBeAccessible/index.ts index 3cc5ede..79472c0 100644 --- a/src/matchers/toBeAccessible/index.ts +++ b/src/matchers/toBeAccessible/index.ts @@ -21,8 +21,7 @@ async function getResults(obj: Handle | AxeResults, options: MatcherOptions) { ok: !results.violations.length } } else { - const handle = obj as Handle - return waitForAxeResults(handle, options) + return waitForAxeResults(obj as Handle, options) } } diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts index d9fe012..ddc32e3 100644 --- a/src/waitForAxeResults.ts +++ b/src/waitForAxeResults.ts @@ -30,4 +30,3 @@ export async function waitForAxeResults( }) } -export default waitForAxeResults From ca83d202c6f08c1d7dbe33680631b9dd155784cc Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Thu, 8 Sep 2022 13:58:21 -0500 Subject: [PATCH 06/14] update tests --- src/waitForAxeResults.spec.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/waitForAxeResults.spec.ts b/src/waitForAxeResults.spec.ts index 12bba2f..88f3a4b 100644 --- a/src/waitForAxeResults.spec.ts +++ b/src/waitForAxeResults.spec.ts @@ -6,14 +6,16 @@ test.describe("waitForAxeResults", () => { test("should be ok for page with no axe violations", async ({ page }) => { const content = await readFile("accessible.html") await page.setContent(content) - const { ok } = await waitForAxeResults(page) - await expect(ok).toBeTruthy() + const { ok, results } = await waitForAxeResults(page) + expect(results.violations).toHaveLength(0) + expect(ok).toBe(true) }) test("should not be ok for page with axe violations", async ({ page }) => { const content = await readFile("inaccessible.html") await page.setContent(content) - const { ok } = await waitForAxeResults(page) - await expect(ok).toBeFalsy() + const { ok, results } = await waitForAxeResults(page) + expect(results.violations.length).toBeGreaterThan(0) + expect(ok).toBe(false) }) }) From 0d2e7a1cb01c9dbb0cc802e8bd180f983f473c3c Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Thu, 8 Sep 2022 17:24:49 -0500 Subject: [PATCH 07/14] prettier --- src/matchers/toBeAccessible/index.ts | 16 ++++++++-------- src/waitForAxeResults.spec.ts | 14 +++++++------- src/waitForAxeResults.ts | 13 ++++++------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/matchers/toBeAccessible/index.ts b/src/matchers/toBeAccessible/index.ts index 79472c0..e0639a7 100644 --- a/src/matchers/toBeAccessible/index.ts +++ b/src/matchers/toBeAccessible/index.ts @@ -14,15 +14,15 @@ const summarize = (violations: Result[]) => .join(', ') async function getResults(obj: Handle | AxeResults, options: MatcherOptions) { - if ((obj as AxeResults).violations) { - const results = obj as AxeResults - return { - results, - ok: !results.violations.length - } - } else { - return waitForAxeResults(obj as Handle, options) + if ((obj as AxeResults).violations) { + const results = obj as AxeResults + return { + results, + ok: !results.violations.length, } + } else { + return waitForAxeResults(obj as Handle, options) + } } export async function toBeAccessible( diff --git a/src/waitForAxeResults.spec.ts b/src/waitForAxeResults.spec.ts index 88f3a4b..a68d172 100644 --- a/src/waitForAxeResults.spec.ts +++ b/src/waitForAxeResults.spec.ts @@ -1,18 +1,18 @@ -import { expect, test } from "@playwright/test" -import { readFile } from "./utils/file" +import { expect, test } from '@playwright/test' +import { readFile } from './utils/file' import { waitForAxeResults } from './waitForAxeResults' -test.describe("waitForAxeResults", () => { - test("should be ok for page with no axe violations", async ({ page }) => { - const content = await readFile("accessible.html") +test.describe('waitForAxeResults', () => { + test('should be ok for page with no axe violations', async ({ page }) => { + const content = await readFile('accessible.html') await page.setContent(content) const { ok, results } = await waitForAxeResults(page) expect(results.violations).toHaveLength(0) expect(ok).toBe(true) }) - test("should not be ok for page with axe violations", async ({ page }) => { - const content = await readFile("inaccessible.html") + test('should not be ok for page with axe violations', async ({ page }) => { + const content = await readFile('inaccessible.html') await page.setContent(content) const { ok, results } = await waitForAxeResults(page) expect(results.violations.length).toBeGreaterThan(0) diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts index ddc32e3..0dcd88f 100644 --- a/src/waitForAxeResults.ts +++ b/src/waitForAxeResults.ts @@ -1,9 +1,9 @@ -import test from "@playwright/test" -import type { AxeResults, RunOptions } from "axe-core" -import { Handle, resolveLocator } from "./utils/locator" -import merge from "merge-deep" -import { poll } from "./utils/poll" -import { injectAxe, runAxe } from "./utils/axe" +import test from '@playwright/test' +import type { AxeResults, RunOptions } from 'axe-core' +import { Handle, resolveLocator } from './utils/locator' +import merge from 'merge-deep' +import { poll } from './utils/poll' +import { injectAxe, runAxe } from './utils/axe' /** * Injects axe onto page, waits for the page to be ready, then runs axe against @@ -29,4 +29,3 @@ export async function waitForAxeResults( } }) } - From 59b10cdfd2f3a181bd5b44c85ff693810f0c1ec9 Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Mon, 26 Sep 2022 17:19:56 -0700 Subject: [PATCH 08/14] add note to changelog, bump version (minor) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b699ce2..627c0b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # expect-axe-playwright +## 2.3.0 + +### Minor Changes + +- 4276db6: Allow matcher to accept Axe results object + ## 2.2.1 ### Patch Changes diff --git a/package.json b/package.json index 32805de..e5b05cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "expect-axe-playwright", - "version": "2.2.1", + "version": "2.3.0", "description": "Expect matchers to perform Axe accessibility tests in your Playwright tests.", "author": "Widen", "license": "ISC", From caf2b1b04305a6c3bcbbd4b2a8f8f1f91a4cbfcb Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Tue, 27 Sep 2022 09:06:26 -0700 Subject: [PATCH 09/14] Revert "add note to changelog, bump version (minor)" This reverts commit 59b10cdfd2f3a181bd5b44c85ff693810f0c1ec9. --- CHANGELOG.md | 6 ------ package.json | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 627c0b4..b699ce2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,5 @@ # expect-axe-playwright -## 2.3.0 - -### Minor Changes - -- 4276db6: Allow matcher to accept Axe results object - ## 2.2.1 ### Patch Changes diff --git a/package.json b/package.json index e5b05cc..32805de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "expect-axe-playwright", - "version": "2.3.0", + "version": "2.2.1", "description": "Expect matchers to perform Axe accessibility tests in your Playwright tests.", "author": "Widen", "license": "ISC", From e6fd3edca12425bef079b8282ab1c3d88c9694b3 Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Tue, 27 Sep 2022 09:07:39 -0700 Subject: [PATCH 10/14] create changeset file --- .changeset/wild-shrimps-mix.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wild-shrimps-mix.md diff --git a/.changeset/wild-shrimps-mix.md b/.changeset/wild-shrimps-mix.md new file mode 100644 index 0000000..5e1ac02 --- /dev/null +++ b/.changeset/wild-shrimps-mix.md @@ -0,0 +1,5 @@ +--- +'expect-axe-playwright': minor +--- + +Allow matcher to accept Axe results object From 1362f15034ef481d0ef01a296c6cff01e6db635a Mon Sep 17 00:00:00 2001 From: gabalafou Date: Tue, 27 Sep 2022 15:51:45 -0500 Subject: [PATCH 11/14] Update src/waitForAxeResults.ts Co-authored-by: Mark Skelton --- src/waitForAxeResults.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts index 0dcd88f..c1a591b 100644 --- a/src/waitForAxeResults.ts +++ b/src/waitForAxeResults.ts @@ -12,10 +12,7 @@ import { injectAxe, runAxe } from './utils/axe' export async function waitForAxeResults( handle: Handle, { timeout, ...options }: { timeout?: number } & RunOptions = {} -): Promise<{ - ok: boolean - results: AxeResults -}> { +) { const info = test.info() const opts = merge(info.project.use.axeOptions, options) const locator = resolveLocator(handle) From 14d5e0071378341527c167e3d294ee56292ab456 Mon Sep 17 00:00:00 2001 From: gabalafou Date: Tue, 27 Sep 2022 19:06:12 -0500 Subject: [PATCH 12/14] Update src/waitForAxeResults.ts --- src/waitForAxeResults.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts index c1a591b..c2af0e9 100644 --- a/src/waitForAxeResults.ts +++ b/src/waitForAxeResults.ts @@ -1,5 +1,5 @@ import test from '@playwright/test' -import type { AxeResults, RunOptions } from 'axe-core' +import type { RunOptions } from 'axe-core' import { Handle, resolveLocator } from './utils/locator' import merge from 'merge-deep' import { poll } from './utils/poll' From 58f440805036bcf52cd6e2e82bfd4030b34b4032 Mon Sep 17 00:00:00 2001 From: Gabriel Fouasnon Date: Wed, 28 Sep 2022 15:19:12 -0700 Subject: [PATCH 13/14] getOptions --- src/matchers/toBeAccessible/index.ts | 7 +++---- src/utils/options.ts | 13 +++++++++++++ src/waitForAxeResults.ts | 6 ++---- 3 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 src/utils/options.ts diff --git a/src/matchers/toBeAccessible/index.ts b/src/matchers/toBeAccessible/index.ts index e0639a7..a7a0be5 100644 --- a/src/matchers/toBeAccessible/index.ts +++ b/src/matchers/toBeAccessible/index.ts @@ -3,8 +3,8 @@ import type { MatcherState } from '@playwright/test/types/expect-types' import type { AxeResults, Result } from 'axe-core' import type { MatcherOptions } from '../../types' import type { Handle } from '../../utils/locator' +import { getOptions } from '../../utils/options' import createHTMLReport from 'axe-reporter-html' -import merge from 'merge-deep' import { attach } from '../../utils/attachments' import { waitForAxeResults } from '../../waitForAxeResults' @@ -33,12 +33,11 @@ export async function toBeAccessible( try { const { results, ok } = await getResults(obj, options) - const info = test.info() - const opts = merge(info.project.use.axeOptions, options) - // If there are violations, attach an HTML report to the test for additional // visibility into the issue. if (!ok) { + const info = test.info() + const opts = getOptions(options) const html = await createHTMLReport(results) const filename = opts.filename || 'axe-report.html' await attach(info, filename, html) diff --git a/src/utils/options.ts b/src/utils/options.ts new file mode 100644 index 0000000..d575974 --- /dev/null +++ b/src/utils/options.ts @@ -0,0 +1,13 @@ +import type { MatcherOptions } from '../types' +import test from '@playwright/test' +import merge from 'merge-deep' + +/** + * Overrides the default options with any user-provided options, and + * returns the final options object. + */ +export function getOptions(options: MatcherOptions = {}) { + const info = test.info() + const opts = merge(info.project.use.axeOptions, options) + return opts +} diff --git a/src/waitForAxeResults.ts b/src/waitForAxeResults.ts index c2af0e9..e7ecfb5 100644 --- a/src/waitForAxeResults.ts +++ b/src/waitForAxeResults.ts @@ -1,9 +1,8 @@ -import test from '@playwright/test' import type { RunOptions } from 'axe-core' import { Handle, resolveLocator } from './utils/locator' -import merge from 'merge-deep' import { poll } from './utils/poll' import { injectAxe, runAxe } from './utils/axe' +import { getOptions } from './utils/options' /** * Injects axe onto page, waits for the page to be ready, then runs axe against @@ -13,8 +12,7 @@ export async function waitForAxeResults( handle: Handle, { timeout, ...options }: { timeout?: number } & RunOptions = {} ) { - const info = test.info() - const opts = merge(info.project.use.axeOptions, options) + const opts = getOptions(options) const locator = resolveLocator(handle) await injectAxe(locator) return poll(locator, timeout, async () => { From 1a0f2ef04157f11bf25823c72a1415cae79d0479 Mon Sep 17 00:00:00 2001 From: Mark Skelton Date: Wed, 28 Sep 2022 17:27:08 -0500 Subject: [PATCH 14/14] Update src/utils/options.ts --- src/utils/options.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/options.ts b/src/utils/options.ts index d575974..36e1323 100644 --- a/src/utils/options.ts +++ b/src/utils/options.ts @@ -8,6 +8,5 @@ import merge from 'merge-deep' */ export function getOptions(options: MatcherOptions = {}) { const info = test.info() - const opts = merge(info.project.use.axeOptions, options) - return opts + return merge(info.project.use.axeOptions, options) }