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

时间:2018-06-19 15:24:34

标签: javascript node.js testing jestjs puppeteer

我有一个基于Jest的基于Puppeteer的小型测试套件,但我无法摆脱以下问题:当我运行一个特定的测试(例如:yarn test myscenario.test.js)时,一切正常。当我使用yarn test命令运行整个测试套件(大约20个测试)时,会出现问题,我的某些测试失败并显示以下错误:

  

超过导航超时:超过30000ms   然后在Promise.then(node_modules / puppeteer / lib / NavigatorWatcher.js:73:21)

问题是我所有的测试都已经设置了特定的超时时间(99999 ms !!),并且单个测试在大约6-7秒内执行。我的猜测是,当整个测试套件运行时,全局导航超时将超过30000ms的限制。

有什么方法可以覆盖此全局导航超时限制?

这是我的其中一项测试(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)
      }
    }
})

对此事有任何暗示,谢谢!

4 个答案:

答案 0 :(得分:2)

要解决实际的问题,“覆盖导航超时”。您可以将timeout选项传递给waitForNavigation方法。

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

您还可以通过传递值0来禁用超时。

但是,我认为您有更大的问题。看来:

  1. 同时运行所有测试文件会导致多个Chromium会话,导致加载时间长。
  2. 您的页面变量正在由试图同时运行的测试共享。

您已经在范围的顶部定义了“页面”,因此,每个测试用例都将共享页面变量的实例。

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);
    }
  }
});

您可能需要用完无头模式才能找出问题所在。

答案 1 :(得分:0)

您是否并行运行测试?您是否在重复使用标签/浏览器?当我的测试套件并行运行时,我遇到了类似的问题,因为它们修改了相同的标签。

此外,您是否尝试以非无头模式启动以检查测试执行过程中到底发生了什么?

答案 2 :(得分:0)

在docker中并行运行测试时遇到类似问题,在args以下启动浏览器大大减少了导航时间,并且测试现在运行良好。

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
]})

有关问题here的更多参考

答案 3 :(得分:0)

puppeteer 超时的默认值为 30 秒。要使用自定义超时,您可以使用 setDefaultNavigationTimeout 和 setDefaultTimeout 方法或 options 参数中的 timeout 属性。所有情况下的等待时间都以毫秒为单位指定。

await page.setDefaultNavigationTimeout(60000);

例如

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

传递 0 以禁用超时

await page.setDefaultNavigationTimeout(0);   

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