Protractor 对browser.getAllWindowHandles的第二次调用导致错误

Protractor 对browser.getAllWindowHandles的第二次调用导致错误,protractor,socketexception,Protractor,Socketexception,在我的量角器脚本中有以下场景:(由于机密性而编辑的某些片段) 我一点一点地构建了它,基本上是在每个屏幕截图之前添加每个片段,确保它在继续下一个片段之前工作。最后一部分,从第二次调用browser.getAllWindowHandles()开始,将使脚本崩溃并生成以下错误: 失败:java.net.SocketException:软件导致的连接中止:recv失败 我可笑地增加了超时时间(如您所见)。我注释掉了browser.close(),以防万一。还没搞定 当我观看测试运行时,它做得很好,甚至单

在我的量角器脚本中有以下场景:(由于机密性而编辑的某些片段)

我一点一点地构建了它,基本上是在每个屏幕截图之前添加每个片段,确保它在继续下一个片段之前工作。最后一部分,从第二次调用
browser.getAllWindowHandles()
开始,将使脚本崩溃并生成以下错误:

失败:java.net.SocketException:软件导致的连接中止:recv失败

我可笑地增加了超时时间(如您所见)。我注释掉了
browser.close()
,以防万一。还没搞定

当我观看测试运行时,它做得很好,甚至单击最后一个按钮,生成最后一个报告。当我第二次叫它拿窗把手时,它就咯咯叫了。我甚至在它出现之前就得到了截图

我在谷歌上搜索了很多,甚至在SO上查找了这个错误,但我仍然不知道它为什么会这样做

谢谢

编辑:所以,我只是尝试了一下,只点击了第二个报告。同样的错误。是不是第二份报告太长了?显然,第二份报告(由动态数据生成的PDF)出了问题。什么样的事情会在生成的PDF中导致此错误

编辑2:我增加了
浏览器。等待
到20秒,仍然可以看到它。我认为这不是时间问题

编辑3(7/5):所以,看起来它实际上可能与时间有关。新的报告窗口需要一点时间才能打开。如果我睡眠5秒钟,我会得到一个错误,它无法找到句柄,因为它不存在。我移动到6秒,得到socketException。这是一个切换到使用
browser.wait()
的候选者吗?在这个场景中我将如何实现它?

明白了

我在某处找到了这段珍贵的片段,它成功了

 browser.driver.wait(function () {
            return browser.getAllWindowHandles().then(function (handles) {

                if (handles.length > 1) {
                    return true;
                }
            });
        }, 10000, 'Waited for window count to be greater than 1');
我在5秒钟的睡眠前插入了这个,效果很好。
另外,要注意的是,当我没有关闭第一个报告窗口时,第二个报告窗口没有位于句柄数组的位置3。它将自己插入位置2,将第一个报告推到位置3。

处理浏览器句柄有时会非常棘手,特别是对于Mozilla和IE11

下面是一个用于以字符串形式检索所有浏览器句柄标题的方法。您可以轻松地调整代码,使其在任何条件下都适用

/**
   * this method helps to get all window titles
   * @param windowTitle
   */
  async getAllRedirectedBrowserWindowTitles() {
    const title: string[] = [];
    await browser.wait(
      async () => {
        return (await browser.getAllWindowHandles()).length >= 2;
      },
      5000,
      `Only one browser handle found. There is no other browser handle to iterate`
    );
    const _windowHandles: string[] = await browser.getAllWindowHandles();
    const _parentHandle: string = _windowHandles[0];
    for (const guid of _windowHandles) {
      if (guid !== _parentHandle) {
        await browser.switchTo().window(guid);
        await browser.wait(
          async () => {
            return (await browser.getTitle()) ? true : false;
          },
          5000,
          `Child browser title not loaded`
        );
        title.push(await browser.getTitle());
        await browser.close();
      }
    }
    await browser.switchTo().window(_parentHandle);
    return title;
  }
现在,您只需要从代码中的任何位置调用此方法:

await getAllRedirectedBrowserWindowTitles(); //this will return the list of window title

快乐编码

2个想法。首先,你可以从Jim Evans那里找到一个很长的讨论,Selenium不能保证任何关于句柄顺序的东西,你真的应该做一些事情,比如检查标题以确定哪一个是最新的弹出窗口。其次,我想知道您是否需要添加一个等待句柄的特性,如browser.wait(windowCount(2),30000,'wait for Second window(popup'))。然后(function(){},function(err){//您可以尝试再次单击此处});其中var windowCount=function(count){return function(){return browser.getAllWindowHandles()。然后(function(handles){return handles.length>=count;};};}//这些都不是我最初的代码,我想它来自@alecxe。另外,我不依赖句柄顺序的意思是使用诸如browser.driver.switchTo().window('claimResultsWindow')之类的东西。还可以使用browser.wait和类似下面的.var claimpupispresent=function(){//副作用--切换到声明弹出窗口,精细返回函数(){return browser.driver.switchTo().window('claimResultsWindow')。然后(function()){return true;},函数(err){return false;};}}}还有两个想法。如果您使用IE,则需要考虑保护模式设置。您可能还需要browser.waitForAngularEnabled(false)除了ingoreSynchronization。谢谢你的评论!这似乎不是一个实际的处理问题。它甚至没有达到这一点。我已经深入研究了更多,似乎我在脚本中遇到了一个无法解释的错误。不知怎的,整个用户故事实际上是可行的,但在某一点上出现了一个错误,表明相关的查询没有定义。所以,我正在努力确定这一点,看看这是否能澄清这一点。
await getAllRedirectedBrowserWindowTitles(); //this will return the list of window title