【问题标题】:How to wait for JavaScript to finish in playwright如何在剧作家中等待 JavaScript 完成
【发布时间】:2021-05-20 21:58:45
【问题描述】:

我正在使用 Playwright 和 JavaScript 测试 UI。我的代码找到了一个输入元素,该元素有时可以是下拉列表,有时是文本,有时是日期。为了解决这个问题,我分两步输入值。首先,我填充文本,然后单击 tab 键调用 JavaScript 来格式化元素中的值。

await page.fill("#myID", inputText); 
await page.keyboard.press('Tab');  // this line trigger the JS

// continue to the next element 

问题,它不是在等待 JavaScript 完成。如何在代码继续之前等待 JS 完成。

【问题讨论】:

    标签: javascript puppeteer playwright


    【解决方案1】:

    使用page.waitFor... 函数

    当满足以page.waitFor 开头的某些条件时,剧作家提供了许多功能(例如page.waitForFunction)。可能page.waitForFunction 是最通用的,因为您可以传递一个等待特定条件满足的自定义函数。

    或者,使用超时

    我认为您可以在页面上下文中使用 setTimeoutpage.evaluate 来等待其他 JavaScript 运行:

    await page.evaluate(() => {
      // if this doesn't work, you can try to increase 0 to a higher number (i.e. 100)
      return new Promise((resolve) => setTimeout(resolve, 0));
    });
    

    这可能相当于page.waitForTimeout(0),但我不确定。请注意,他们建议不要在生产环境中使用 page.waitForTimeout

    【讨论】:

    • 不幸的是,在这种情况下不好。这种模式发生了很多次,如果我使用硬编码值,脚本会很慢。 JS完成后我需要停止等待。
    • 您可以尝试使用 0 超时,这可能会起作用,具体取决于事件如何冒泡,或者您可以将其抽象为允许您传递 timeout 参数的函数。如果这不起作用,则很难确定 JS 何时“完成”,而无需明确编写表明已完成的代码(例如,如果您可以编辑客户端代码,则可以有一个名为 doneClientSide() 的自定义函数,您可以在剧作家中检查)。我感觉您通常会遇到性能问题。
    • 我认为 waitForFunction 可能会有所帮助,尽管这并不容易。我需要检查。谢谢!
    【解决方案2】:

    您可能会发现这很有用,(https://repl.it/join/bkgmwcjv-vladimirlisove1)。 https://developer.mozilla.org/enUS/docs/Web/JavaScript/Reference/Statements/async_function.

    function resolveAfter2Seconds() {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve('resolved');
        }, 2000);
      });
    }
    
    async function asyncCall() {
      console.log('calling');
      const result = await resolveAfter2Seconds();
      console.log(result);
      // expected output: "resolved"
    }
    
    asyncCall();
    

    或者,从freecodecamp找到一个例子,看起来更简单:

    const promise = new Promise((resolve, reject) => {  
    
      setTimeout(function(){ 
        resolve(); // Task is completed
      }, 3000);
    
      return resolve;
    });
    
    promise.then(res => {
      console.log('resolved');
    }).catch(err => {
        console.log(err)
    });
    

    【讨论】:

    • 在这种情况下我不能使用硬编码等待。该模式出现多次,如果我使用硬编码等待,脚本会很慢。 JS完成后我需要停止等待。
    • 如果您的解决方案是等待 X 秒,那么您就输了。您的测试执行起来会很慢,并且会随机失败。
    【解决方案3】:

    您可以等待对您的点击做出反应(某些页面更改,或发出 HTTP 请求),例如:

    【讨论】:

      猜你喜欢
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2021-10-08
      • 1970-01-01
      相关资源
      最近更新 更多