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

Puppeteer hangs when page has lazy loaded iframe #727

Closed
straker opened this issue May 10, 2023 · 1 comment · Fixed by #752
Closed

Puppeteer hangs when page has lazy loaded iframe #727

straker opened this issue May 10, 2023 · 1 comment · Fixed by #752

Comments

@straker
Copy link
Contributor

straker commented May 10, 2023

When a page has an iframe with loading="lazy" attribute and that has not been scrolled into view, Puppeteer will hang indefinitely if you try to interact with a non-loaded iframe (e.g. using frame.$$(selector) never throws nor completes). What that means is if you try to scan a page with such an iframe the analyze will never finish (e.g. https://www.rastoder.si/).

We should inform the user that the iframe isn't loaded and skip it like we do when we can't inject axe into the iframe.

@padmavemulapati
Copy link

padmavemulapati commented Oct 11, 2023

Verified with the latest canary-build (4.7.4-62fd241.0)
Lazy-loaded iframes are scanning properly now, not hanging,

1. Here is iframes snippets:

lazyloadedIframe.html

<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en" id="lazy-loading-iframe-root">
  <head>
    <title>Lazy Loading Iframe Root</title>
  </head>
  <body>
    <main>
      <h1>iframe context test</h1>
      <div style="margin-top: 300vh">
        <iframe src="iframes/lazy.html" id="ifr-lazy" loading="lazy"></iframe>
      </div>
    </main>
  </body>
</html>
2. for this iframes - directory has a lazy.html file too

./iframes.lazy.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Lazy</title>
  </head>
  <body>
    <h1>Lazy</h1>
    <div style="margin-top: 300vh">
      <iframe id="lazy-iframe" src="https://www.youtube.com/embed/REDRiwmNunA" title="MONTHLY SPOTLIGHT" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy"></iframe>
      <iframe src="baz.html" id="lazy-baz"></iframe>
    </div>
  </body>
</html>
3. For Puppeteer found - `frame-tested` incomplete result and `frame-title` failure too.

test-script:

const { AxePuppeteer } = require('@axe-core/puppeteer');
const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.setBypassCSP(true);
  await page.goto('http://localhost:8081/iframesfixture.html');
  const results = await new AxePuppeteer(page).analyze();
    fs.writeFile("./lazyframes_frametested.json", JSON.stringify(results, null,4),(err)=>
    {if(err){
        console.error(err);
        return;
        };
        console.log("File has been created");
    })

  await page.close();
  await browser.close();
})();

Results:

image

4.for webdriverjs:

Test-script:

const { AxeBuilder } = require('@axe-core/webdriverjs');
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const fs = require('fs');

(async () => {
  const driver = new Builder()
    .forBrowser('chrome')
    .setChromeOptions(new chrome.Options().headless())
    .build();
  await driver.get('http://localhost:8081/iframesfixture.html');
  try {
    const results = await new AxeBuilder(driver).analyze();
    fs.writeFile("./lazyiframestest.json", JSON.stringify(results, null,4),(err)=>
    {if(err){
        console.error(err);
        return;
        };
        console.log("File has been created");
    })
  } catch (e) {
    // do something with the error
  }

  await driver.quit();
})();
  

Result:

image

5. for CLI - command is `axe http://localhost:8081/iframesfixture.html --save ./iframesresult1 `

image

6. for webdriverio:

TestScript:

const AxeBuilder = require('@axe-core/webdriverio').default;
const { remote } = require('webdriverio');
const fs = require('fs');

(async () => {
  const client = await remote({
    logLevel: 'error',
    capabilities: {
      browserName: 'chrome'
    }
  });

  await client.url('http://localhost:8081/iframesfixture.html');

  const builder = new AxeBuilder({ client });
  //const results = await builder.include('#shadow-root-2').analyze();
  const results = await builder.analyze();
    fs.writeFile("./lazyiframestest.json", JSON.stringify(results, null,4),(err)=>
    {if(err){
        console.error(err);
        return;
        };
        console.log("File has been created");
    })
   client.deleteSession();
})();


Result:

image

7. for Playwright:

TestScript:

const { AxeBuilder } = require('@axe-core/playwright');
const playwright = require('playwright');
const fs = require('fs');
const { assert } = require('chai')
const axeSource = fs.readFileSync('./axeSource223.min.js', 'utf8');
describe('Accessibility Site Scan with axe-core playwright', () => {
 let browser;
  let context;
  let page;

  before(async function () {
     browser = await playwright.chromium.launch({ headless: true });
     context = await browser.newContext();
     page = await context.newPage();
  });

  after(async function () {
    await browser.close();
  });


  it('should scan the test page',
    async function () {
       await page.goto('http://localhost:8081/iframesfixture.html');
         const results = await new AxeBuilder({page}).analyze();
        fs.writeFile("./lazyloadPlaywright.json", JSON.stringify(results, null, 4), (err) => {
        if (err) {
          console.error(err);
          return;
        };
        })
      });
});

Result:

image

Environment:

Label Value
Product axe-core-npm/puppeteer
Version 4.7.4-62fd241.0
OS-Details _MAC- Intel Core i7 - 11.6.8 & Windows11 _
BrowserDetails Chrome Version 117.0.5938.88 (Official Build) (64-bit) & Firefox 117.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants