Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(playwright): skip unloaded iframes #1060

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"axe-core": "~4.9.0"
},
"devDependencies": {
"@playwright/test": "^1.34.3",
"@playwright/test": "^1.44.0",
"@types/chai": "^4.3.3",
"@types/express": "^4.17.14",
"@types/mocha": "^10.0.0",
Expand Down
22 changes: 18 additions & 4 deletions packages/playwright/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,24 @@ export default class AxeBuilder {
* @returns Promise<void>
*/

private async inject(frames: Frame[]): Promise<void> {
private async inject(frames: Frame[], shouldThrow?: boolean): Promise<void> {
for (const iframe of frames) {
await iframe.evaluate(await this.script());
await iframe.evaluate(await this.axeConfigure());
const race = new Promise((_, reject) => {
Copy link
Contributor Author

@straker straker May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newer versions of Playwright with the update to Chrome, combined with our changes to the lazy loaded frame test now make it so Playwright is not loading the lazy loaded iframe when it is outside the viewport.

Playwright does not have a pageload timeout like all the other drivers, and neither does the evaluate function have a timeout option. So this was the only other choice to have the lazy loaded iframe not hang indefinitely.

setTimeout(() => {
reject(new Error('Script Timeout'));
Zidious marked this conversation as resolved.
Show resolved Hide resolved
}, 1000);
});
const evaluate = iframe.evaluate(this.script());

try {
await Promise.race([evaluate, race]);
await iframe.evaluate(await this.axeConfigure());
} catch (err) {
// in legacy mode we don't want to throw the error we just want to skip injecting into the frame
if (shouldThrow) {
throw err;
}
}
}
}

Expand Down Expand Up @@ -256,7 +270,7 @@ export default class AxeBuilder {
iframeHandle.asElement() as ElementHandle<Element>;
const childFrame = await iframeElement.contentFrame();
if (childFrame) {
await this.inject([childFrame]);
await this.inject([childFrame], true);
childResults = await this.runPartialRecursive(
childFrame,
frameContext
Expand Down
7 changes: 6 additions & 1 deletion packages/playwright/test/axe-playwright.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,12 @@ describe('@axe-core/playwright', () => {
.analyze();

assert.equal(res?.status(), 200);
assert.lengthOf(results.incomplete, 0);
assert.equal(results.incomplete[0].id, 'frame-tested');
assert.lengthOf(results.incomplete[0].nodes, 1);
assert.deepEqual(results.incomplete[0].nodes[0].target, [
'#ifr-lazy',
'#lazy-iframe'
]);
assert.equal(results.violations[0].id, 'label');
assert.lengthOf(results.violations[0].nodes, 1);
assert.deepEqual(results.violations[0].nodes[0].target, [
Expand Down
Loading