导航后编剧错误(目标已关闭)

Posted

技术标签:

【中文标题】导航后编剧错误(目标已关闭)【英文标题】:Playwright error (Target closed) after navigation 【发布时间】:2020-09-08 00:33:37 【问题描述】:

我正在尝试一些非常简单的事情:

导航到 google.com 用“奶酪”填充搜索框 在搜索框中按回车键 打印第一个结果的标题文本

如此简单,但我无法让它工作。这是代码:

const playwright = require('playwright');

(async () => 
  for (const browserType of ['chromium', 'firefox', 'webkit']) 
    const browser = await playwright[browserType].launch();
    try 
      const context = await browser.newContext();
      const page = await context.newPage();
      await page.goto('https://google.com');
      await page.fill('input[name=q]', 'cheese');
      await page.press('input[name=q]', 'Enter');
      await page.waitForNavigation();

      page.waitForSelector('div#rso h3')
          .then(firstResult => console.log(`$browserType: $firstResult.textContent()`))
          .catch(error => console.error(`Waiting for result: $error`));
     catch(error) 
      console.error(`Trying to run test on $browserType: $error`);
     finally 
      await browser.close();
    
  
)();

起初我尝试使用page.$() 获得第一个结果,但没有成功。在稍微调查了这个问题后,我发现我认为page.waitForNavigation() 会是解决方案,但事实并非如此。

我用的是最新的编剧版本:1.0.2。

【问题讨论】:

这可能不是您的问题,而是其他任何人在谷歌上搜索此错误:如果您的测试在waitForNavigation 调用期间超时,您将获得“目标关闭”。在这种情况下,它还会在控制台输出中显示Timeout of XXXms exceeded. 【参考方案1】:

在我看来,唯一的问题是您最初的承诺组合,我刚刚将承诺重构为 async/await 并使用 page.$eval 检索 textContent 它完美地工作,没有 目标已关闭错误了。

try 
      const context = await browser.newContext();
      const page = await context.newPage();
      await page.goto('https://google.com');
      await page.fill('input[name=q]', 'cheese');
      await page.press('input[name=q]', 'Enter');
      await page.waitForNavigation();

      // page.waitForSelector('div#rso h3').then(firstResult => console.log(`$browserType: $firstResult.textContent()`)).catch(error => console.error(`Waiting for result: $error`));

      await page.waitForSelector('div#rso h3');
      const firstResult = await page.$eval('div#rso h3', firstRes => firstRes.textContent);
      console.log(`$browserType: $firstResult`)
     catch(error) 
      console.error(`Trying to run test on $browserType: $error`);
     finally 
      await browser.close();
    
  

输出:

chrome: Cheese – Wikipedia
firefox: Cheese – Wikipedia
webkit: Cheese – Wikipedia

注意: chrome 和 webkit 可以工作,firefox 在 waitForNavigation 上对我来说失败了。如果我用await page.waitForTimeout(5000); 替换它,firefox 也可以。这可能是剧作家的 Firefox 对导航承诺的支持问题。

【讨论】:

【参考方案2】:

如果您等待page.press('input[name=q]', 'Enter');,那么waitForNavigation 工作可能为时已晚。

您可以在新闻发布会上删除await。您可能需要等待导航,而不是按下操作。

const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://google.com');
await page.fill('input[name=q]', 'cheese');
page.press('input[name=q]', 'Enter');
await page.waitForNavigation();

var firstResult = await page.waitForSelector('div#rso h3');
console.log(`$browserType: $await firstResult.textContent()`);

另请注意,您需要await 才能获得textContent()

【讨论】:

等待还是不等待 page.pres() 我认为这无关紧要。我已经尝试过你不等待的建议,但我仍然遇到同样的错误。那不是问题。问题是它在导航后不知何故失去了上下文。 我遇到了同样的问题。它在导航之前使用页面的上下文。你有没有找到解决方案?【参考方案3】:

    在我的情况下,Playwright 错误Target closed 出现在第一次尝试从页面检索文本时。 错误不准确,实际原因是在目标站点中启用了基本身份验证。 Playwright 无法打开页面,只是停留在“目标已关闭”。

    const options =  
       httpCredentials =  username: 'user', password: 'password'
    ;
    const context = await browser.newContext(options);
    

    另一个问题是本地测试运行没有问题,包括 docker 容器,而 Github CI 在 Playwright 上失败,除了上述错误之外没有任何细节。 原因是 Github Secret 中有一个特殊符号。例如,美元符号 $ 将从 Github Actions 中的机密中删除。要更正它,请使用env: 部分

    env:
      XXX: $ secrets.SUPER_SECRET 
    

    或将秘密用单引号括起来:

    run: |
      export XXX='$ secrets.YYY'
    

    在 Kubernetes、Docker 和 Gitlub 中存在类似的转义特性; $$ 变为 $z$abc 变为 z

    使用来自 Microsoft 的 mcr.microsoft.com/playwright docker hub 映像,并预装了节点、npm 和 playwright。或者在 playwright 安装过程中不要忘记通过运行 npx playwright install-deps 来安装系统包依赖项。

    VM 应该有足够的资源来处理浏览器测试。 CI/CD 工作流中的一个常见问题。

【讨论】:

Artur,你能分享一些浏览器启动和 dockerfile 的配置吗?我被困在一个类似的问题上。我在 GKE 中运行自动浏览器并看到同样的错误。在我的主机笔记本电脑上本地运行它们或在我的笔记本电脑上运行 docker 容器都可以正常工作。

以上是关于导航后编剧错误(目标已关闭)的主要内容,如果未能解决你的问题,请参考以下文章

Puppeteer - 协议错误(Page.navigate):目标已关闭

Flutter:来自后退导航的回调产生“错误状态:调用关闭后无法添加新事件”

“创建目标表后架构已更改”错误如何发生?

安装VS 2015更新2后,“基础连接已关闭:发送时发生意外错误”

编剧错误:未下载 Firefox 修订版。运行“npm install”或“yarn install”

c# topmost模式窗口关闭后,有“无法访问已释放的对象”错误