简体   繁体   English

使用 Jest 运行 Puppeteer 测试时如何增加导航超时

[英]How to increase Navigation Timeout when running Puppeteer tests with Jest

I have a small suite of tests based on Puppeteer with Jest, and I can't get rid of the following problem: when I am running a single specific test (ex: yarn test myscenario.test.js ) everything works just fine;我有一小套基于 Puppeteer 和 Jest 的测试,但我无法摆脱以下问题:当我运行单个特定测试(例如: yarn test myscenario.test.js )时,一切正常; the problem occurs when I am running the entire test suite (about 20 tests) using yarn test command, some of my tests are failing with following error:当我使用yarn test命令运行整个测试套件(大约 20 个测试)时出现问题,我的一些测试失败并出现以下错误:

Navigation Timeout Exceeded: 30000ms exceeded at Promise.then (node_modules/puppeteer/lib/NavigatorWatcher.js:73:21)超过导航超时:Promise.then 超过 30000 毫秒 (node_modules/puppeteer/lib/NavigatorWatcher.js:73:21)

The thing is that all my tests already have a specific timeout already set (99999 ms !!) and a single test is executed in about 6-7 seconds.问题是我所有的测试都已经设置了特定的超时时间(99999 毫秒 !!),并且单个测试在大约 6-7 秒内执行。 My guess is that when the entire test suite is running, there is a global navigation timeout which exceeds the limits of 30000ms.我的猜测是,当整个测试套件运行时,存在超过 30000 毫秒限制的全局导航超时。

Is there any way to override this global Navigation Timeout limit?有没有办法覆盖这个全局导航超时限制?

Here is how one of my tests ( myscenario.test.js ) looks like (which iterates through a JSON file and navigates to various URLs where executes some simple actions):这是我的一个测试( myscenario.test.js )的样子(它遍历一个 JSON 文件并导航到执行一些简单操作的各种 URL):

 const puppeteer = require('puppeteer') const propertiesReader = require('properties-reader') const jsonReader = require("fs") const prop = propertiesReader('./resources/config.ini') const tealiumTags = JSON.parse(jsonReader.readFileSync('./resources/tealium-tags.json', 'utf8')) let browser let page beforeEach (async () => { browser = await puppeteer.launch({headless: true, args: ['--start-maximized']}); page = await browser.newPage(); await page.setViewport({ width: 1920, height: 1080 }) }) afterEach (() => { browser.close() }) describe('Decline all Tealium tags', () => { for (let brand in tealiumTags) { if (tealiumTags.hasOwnProperty(brand)) { let brandUrl = tealiumTags[brand].url test('Decline all Tealium tags for ' + brandUrl, async () => { console.log("---------------------------------------") console.log("Decline all Tealium tags for " + brandUrl) await page.goto("https://www." + brandUrl, { waitUntil: 'domcontentloaded' }) await page.waitForSelector(prop.get('DECLINE_COOKIES_BUTTON')) await page.click(prop.get('DECLINE_COOKIES_BUTTON')) await page.waitForNavigation({waitUntil: 'domcontentloaded'}) let utag = await page.evaluate(() => window.utag["send"]) expect(Object.keys(utag).length).toEqual(0) }, 99999) } } })

Any hint on this matter would be much appreciated, thanks!任何有关此事的提示将不胜感激,谢谢!

To address the actual question, "overriding the navigation timeout".为了解决实际问题,“覆盖导航超时”。 You can pass the timeout option to the waitForNavigation method.您可以将超时选项传递给 waitForNavigation 方法。

page.waitForNavigation( { timeout: 60, waitUntil: 'domcontentloaded' });

You can also disable the timeout by passing the value 0.您还可以通过传递值 0 来禁用超时。

However, I think you have a bigger problem.但是,我认为你有一个更大的问题。 It seems:它似乎:

  1. Running all tests files at the same time is causing multiple Chromium sessions causing long load times.同时运行所有测试文件会导致多个 Chromium 会话导致加载时间过长。
  2. You page variable is being shared by tests trying to run at the same time.您的页面变量正被尝试同时运行的测试共享。

You've defined 'page' at the top of the scope, therefore, every test case is going to share the instance of the page variable.您已经在范围的顶部定义了“页面”,因此,每个测试用例都将共享页面变量的实例。

let browser;

beforeAll(async () => {
  browser = await puppeteer.launch({ headless: true, args: ['--start-maximized'] });
});

afterAll(() => {
  browser.close();
});

describe('Decline all Tealium tags', () => {
  for (const brand in tealiumTags) {
    if (tealiumTags.hasOwnProperty(brand)) {
      const brandUrl = tealiumTags[brand].url;

      test(`Decline all Tealium tags for ${brandUrl}`, async () => {
        // Setup the page in each test case allows you to run these concurrently.
        const page = await browser.newPage();
        await page.setViewport({ width: 1920, height: 1080 });

        console.log('---------------------------------------');
        console.log(`Decline all Tealium tags for ${brandUrl}`);
        await page.goto(`https://www.${brandUrl}`, { waitUntil: 'domcontentloaded' });
        await page.waitForSelector(prop.get('DECLINE_COOKIES_BUTTON'));
        await page.click(prop.get('DECLINE_COOKIES_BUTTON'));
        await page.waitForNavigation({ waitUntil: 'domcontentloaded' });

        const utag = await page.evaluate(() => window.utag.send);

        expect(Object.keys(utag)).toHaveLength(0);
      }, 99999);
    }
  }
});

You might need to run out of headless mode to isolate the problem.您可能需要退出无头模式来隔离问题。

Faced similar issue when running tests in parallel in docker, launching browser with below args greatly reduced navigation time and the tests are running fine now.在 docker 中并行运行测试时遇到了类似的问题,使用以下参数启动浏览器大大减少了导航时间,并且测试现在运行良好。

await puppeteer.launch({args: [
    '--disable-gpu',
    '--disable-dev-shm-usage',
    '--disable-setuid-sandbox',
    '--no-first-run',
    '--no-sandbox',
    '--no-zygote',
    '--single-process', // <- this one doesn't works in Windows
]})

More reference on issue here关于问题的更多参考here

Are you running the tests in parallel?您是否并行运行测试? Are you reusing tabs/browsers?您是否重复使用标签页/浏览器? I had a similar issue when my test suites were running in parallel, since they modify the same tab.当我的测试套件并行运行时,我遇到了类似的问题,因为它们修改了相同的选项卡。

Also, did you try to launch in non-headless mode to check what exactly is happening during the test execution?此外,您是否尝试以非无头模式启动以检查测试执行期间到底发生了什么?

The default in puppeteer timeout is 30 seconds. puppeteer 超时的默认值为 30 秒。 To use custom timeouts, you can use the setDefaultNavigationTimeout and setDefaultTimeout methods or the timeout property in the options parameter.要使用自定义超时,您可以使用 setDefaultNavigationTimeout 和 setDefaultTimeout 方法或 options 参数中的 timeout 属性。 The wait time in all cases is specified in milliseconds.所有情况下的等待时间都以毫秒为单位指定。

await page.setDefaultNavigationTimeout(60000);

eg例如

const page = await browser.newPage();            
await page.setDefaultNavigationTimeout(60000); //timeout 60 seconds now

Pass 0 to disable the timeout传递 0 以禁用超时

await page.setDefaultNavigationTimeout(0);   

Github Official docs: https://github.com/puppeteer/puppeteer/blob/v10.0.0/docs/api.md#pagesetdefaultnavigationtimeouttimeout Github 官方文档: https : //github.com/puppeteer/puppeteer/blob/v10.0.0/docs/api.md#pagesetdefaultnavigationtimeouttimeout

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM