Javascript 如何在使用Jest运行Puppeter测试时增加导航超时

Javascript 如何在使用Jest运行Puppeter测试时增加导航超时,javascript,node.js,testing,jestjs,puppeteer,Javascript,Node.js,Testing,Jestjs,Puppeteer,我有一个基于Puppeter with Jest的小测试套件,我无法摆脱以下问题:当我运行一个特定的测试时,例如:纱线测试myscenario.test.js,一切正常;当我使用纱线测试命令运行整个测试套件(大约20个测试)时会出现问题,我的一些测试失败,出现以下错误: 超过导航超时:超过30000ms 在Promise.then节点_modules/puppeter/lib/NavigatorWatcher.js:73:21 问题是,我所有的测试都已经有了一个特定的超时,已经设置为999999

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

超过导航超时:超过30000ms 在Promise.then节点_modules/puppeter/lib/NavigatorWatcher.js:73:21

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

有没有办法覆盖此全局导航超时限制

下面是我的一个测试myscenario.test.js的样子,它遍历一个JSON文件并导航到各种URL,在那里执行一些简单的操作:

const puppeter=需要“puppeter” const propertiesReader=需要'properties-reader' const jsonReader=requirefs const prop=propertiesReader'/resources/config.ini' const tealiumTags=JSON.parsejsonReader.readFileSync'./resources/tealium tags.JSON','utf8' 让浏览器 翻页 beforeach异步=>{ browser=wait puppeter.launch{headless:true,args:['-start maximized']}; page=wait browser.newPage; 等待page.setViewport{宽度:1920,高度:1080} } 之后=>{ browser.close } 描述“拒绝所有Tealium标签”,=>{ 让品牌融入教学{ 如果tealiumTags.hasOwnPropertybrand{ 让brandUrl=tealiumTags[brand].url 测试'+brandUrl,async=>{ console.log-------------------- console.log拒绝+brandUrl的所有Tealium标记 等待页面。gotohttps://www. +brandUrl,{waitUntil:'domcontentloaded'} 等待页面。等待SelectorProp。获取“拒绝”按钮 等待页面。单击道具。获取“拒绝”按钮 wait page.waitForNavigation{waitUntil:'domcontentloaded'} 让utag=wait page.evaluate=>window.utag[send] expectObject.keysutag.length.toEqual0 }, 99999 } }
} 你在并行运行这些测试吗?您是否重复使用选项卡/浏览器?当我的测试套件并行运行时,我遇到了类似的问题,因为它们修改了相同的选项卡


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

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


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

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

page.waitForNavigation( { timeout: 60, waitUntil: 'domcontentloaded' });
您还可以通过传递值0来禁用超时

然而,我认为你有一个更大的问题。似乎:

同时运行所有测试文件会导致多个Chromium会话,导致加载时间过长。 您的页面变量正被尝试同时运行的测试共享。 您已经在范围的顶部定义了“page”,因此,每个测试用例都将共享page变量的实例

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

您可能需要运行无头模式以隔离问题。

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

page.waitForNavigation( { timeout: 60, waitUntil: 'domcontentloaded' });
您还可以通过传递值0来禁用超时

然而,我认为你有一个更大的问题。似乎:

同时运行所有测试文件会导致多个Chromium会话,导致加载时间过长。 您的页面变量正被尝试同时运行的测试共享。 您已经在范围的顶部定义了“page”,因此,每个测试用例都将共享page变量的实例

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

您可能需要使用headless模式来隔离问题。

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

更多关于这个问题的参考

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

更多参考问题

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

await page.setDefaultNavigationTimeout(60000);
e、 g

传递0以禁用超时

await page.setDefaultNavigationTimeout(0);   

>Github官方文档:

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

await page.setDefaultNavigationTimeout(60000);
e、 g

传递0以禁用超时

await page.setDefaultNavigationTimeout(0);   

Github官方文档:

我已经按照您的建议进行了调整,但不幸的是,问题仍然存在。现在有一点很清楚,问题是由于并行执行测试而产生的。只需尝试使用npm test--runInBand按顺序运行测试,即可正确执行套件,不再出现超时错误。我会记住你的建议,并尝试重新思考一下测试结构。如果有任何积极的结果,我会告诉你们:谢谢你们的帮助!只是出于好奇,如果您更改browser.close会发生什么情况;等待浏览器。关闭;?刚刚尝试过,不幸的是,同样的问题…我在每个箭头函数后添加了异步,将wait browser.close放在后面,并将puppeter降级为1.1.1,以便代码再次工作,但超时问题仍然存在。生成了多少测试用例?我开始觉得你的内存不足了。您可能需要继续使用runInBand或设置最大工作线程数。使用Thread test命令,在整个套件中总共20个测试脚本中同时执行3个独立的测试脚本,但每个测试脚本都在一个测试数据文件中迭代,并对多个网站执行相同的操作。因此,这可能是我得到超时的原因,因为有时我在按顺序执行测试时会遇到相同的错误。我已经按照您的建议进行了调整,但不幸的是,问题仍然存在。现在有一点很清楚,问题是由于并行执行测试而产生的。只需尝试使用npm test--runInBand按顺序运行测试,即可正确执行套件,不再出现超时错误。我会记住你的建议,并尝试重新思考一下测试结构。如果有任何积极的结果,我会告诉你们:谢谢你们的帮助!只是出于好奇,如果您更改browser.close会发生什么情况;等待浏览器。关闭;?刚刚尝试过,不幸的是,同样的问题…我在每个箭头函数后添加了异步,将wait browser.close放在后面,并将puppeter降级为1.1.1,以便代码再次工作,但超时问题仍然存在。生成了多少测试用例?我开始觉得你的内存不足了。您可能需要继续使用runInBand或设置最大工作线程数。使用Thread test命令,在整个套件中总共20个测试脚本中同时执行3个独立的测试脚本,但每个测试脚本都在一个测试数据文件中迭代,并对多个网站执行相同的操作。因此,这可能是我获得超时的原因,因为有时我在按顺序执行测试时会遇到相同的错误。每个测试都会使用新的选项卡打开一个新的浏览器实例,但是,是的,问题似乎是由于并行执行而发生的。当使用npm测试时,套件被正确执行——runInBand,不再出现超时问题。我将尝试调查并理解如何创建测试结构,以避免并行运行时出现超时问题。谢谢你的帮助!每个测试都会使用一个新的选项卡打开一个新的浏览器实例,但是是的,问题似乎是由于并行执行而发生的。当使用npm测试时,套件被正确执行——runInBand,不再出现超时问题。我将尝试调查并理解如何创建测试结构,以避免并行运行时出现超时问题。谢谢你的帮助!谢谢,我要试试看!:谢谢,我要试试看!:当您得到TimeoutError时,是否尝试多次尝试使用递归?当您得到TimeoutError时,是否尝试多次尝试使用递归?