【问题标题】:Jest-js Pupetter await puppeteer launch newPage returns undefinedJest-js Puppetter 等待 puppeteer 启动 newPage 返回未定义
【发布时间】:2019-02-11 15:52:56
【问题描述】:

我想使用 puppetter 运行测试,我使用 puppetter beforeAll 设置测试并使用 done 参数完成设置

beforeAll(async (done) => {  
  try{
    browser = await puppeteer.launch({
      headless: false,
      slowMo: 20,
      args: [`--window-size=${width},${height}`]
    })
    page = await browser.newPage()
    await page.setViewport({ width, height })
    done()
  } catch (e){
    fail("SETUP FAILED:\n"+e)
  }
}

test,测试将在beforeAlldone 之后运行,对吗?

test('Test Invalid Username Password', async () => {
    try {
      await page.goto(APP_URL)
      await page.click('[data-testid="form-username"]')
      await page.keyboard.type(username)
      //omitted
    } catch (e) {
      fail('AN EXCEPTION IS THROWED\n'+e)
    }
  }, 200000);

我收到错误Cannot read property 'goto' of undefined"

为什么它有时会返回undefined 而有时却不返回? 我想这是因为铬还没有准备好?但是我已经写了await,还不够吗?

在铬准备好使用之前还有什么要检查的?不是未定义?

更新

未定义时的错误

Test Invalid Username Password

    Failed: "AN EXCEPTION IS THROWED
    TypeError: Cannot read property 'goto' of undefined"

      51 |       expect(errorMessage).toEqual(loginExpectedResult.TEST_INVALID_USERNAME_AND_PASSWORD)
      52 |     } catch (e) {
    > 53 |       fail('AN EXCEPTION IS THROWED\n'+e)
         |       ^
      54 |     }
      55 |   }, 200000);
      56 |

      at Env.fail (node_modules/jest-jasmine2/build/jasmine/Env.js:656:39)
      at Object.fail (test/logintest/login.test.js:53:7)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:65:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:303:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:117:21)
      at asyncGeneratorStep (test/logintest/login.test.js:17:103)
      at _next (test/logintest/login.test.js:19:194)
      at test/logintest/login.test.js:19:364
      at Object.<anonymous> (test/logintest/login.test.js:19:97)

fail() 或许来自茉莉花?我使用 VSCode 自动完成功能找到了它。我以为是 Jest 的。不能用吗?

【问题讨论】:

    标签: jestjs puppeteer


    【解决方案1】:

    尝试将 fail("SETUP FAILED:\n"+e) 调用更改为 console.log("SETUP FAILED:\n"+e) 并告诉我们它记录的内容。

    我开始重现您的问题时遇到了同样的问题,因为我忘记了 require('puppeteer') 命令,例如...

    更多注意事项:

      1234563甚至从传递的参数中删除它
    • 你打电话给fail,但它是在哪里定义的?

    • 删除所有内容周围的大 try/catch,测试会自动失败,并在出现错误时提供有用的见解,额外的包围 try/catch 不会给您带来任何优势并使您的测试更加冗长

    如果有帮助请告诉我?

    更新

    在 cmets 中关于它的另一个问题是

    哦,我在哪里可以找到 beforeAll 等待异步函数完成的文档?

    好吧,我从头说起:

    'beforeAll' 函数只是一个普通的 JS 函数

    beforeAll(() => {  
      // do your sync stuff
    }
    

    所以如果你在里面做一些异步的东西

    beforeAll(() => {  
      setTimeout(() => {
        // ...
      }, 1000);
    }
    

    它不知道它应该等待什么,这就是你可以利用done函数的原因

    beforeAll((done) => {  
      setTimeout(() => {
        done();
      }, 1000);
    }
    

    所以在您手动调用 done 函数本身之前,Jest 不会认为它“完成”。 承诺的相同值

    beforeAll((done) => {  
      yourFunctionThatReturnsAPromise(() => {
        done();
      });
    }
    

    或一些承诺连接

    beforeAll((done) => {  
      yourFunctionThatReturnsAPromise(() => {
        return anotherPromise();
      }).then(() => {
        return anotherPromise();
      }).then(() => {
        done();
      });
    }
    

    我们可以缩短它更多

    beforeAll((done) => {  
      yourFunctionThatReturnsAPromise(() => anotherPromise())
        .then(() => anotherPromise())
        .then(() => done());
    }
    

    异步/等待 添加async/await 是为了更好地管理承诺链,让我们看看如何转换后一个功能

    beforeAll(async (done) => {  
      await yourFunctionThatReturnsAPromise())
      await anotherPromise();
      done();
    }
    
    • 我们await每一个承诺
    • 我们将async 添加到传递给beforeAll 的函数中

    这样做会自动等待每个 Promise,我们告诉 JS 我们的函数是异步的,它会在考虑我们的函数完成之前自动等待 Promise 完成。而且由于它会自动等待...我们现在可以删除 done 使用

    beforeAll(() => {  
      await yourFunctionThatReturnsAPromise())
      await anotherPromise();
    }
    

    现在我们可以将它应用到您的脚本中:请记住,几乎每个 Puppeteer 的函数都会返回一个 Promise,因此我们可以像这样编写一个设置函数

    beforeAll((done) => {  
      puppeteer.launch({
        headless: false,
        slowMo: 20,
        args: [`--window-size=${width},${height}`]
      }).then(browser => {
        return browser.newPage();
      }).then(page => {
        return page.setViewport({ width, height });
      }).then(() => {
        done();
      })
    }
    

    并将其转换为原始的

    beforeAll(async (done) => {  
      browser = await puppeteer.launch({
        headless: false,
        slowMo: 20,
        args: [`--window-size=${width},${height}`]
      })
      page = await browser.newPage()
      await page.setViewport({ width, height })
      done()
    }
    

    但由于它是一个异步函数,而你 await 所有 Puppeteer 的调用,你现在可以删除 done 函数

    beforeAll(async () => {  
      browser = await puppeteer.launch({
        headless: false,
        slowMo: 20,
        args: [`--window-size=${width},${height}`]
      })
      page = await browser.newPage()
      await page.setViewport({ width, height })
    }
    

    因为 async 函数是自动等待的,所以它不会在没有等待承诺(显然是你 await 的承诺)得到解决的情况下结束。

    【讨论】:

    • 我已经更新了问题,哦,我在哪里可以找到beforeAll 等待异步函数完成的文档?我只能找到使用promise 和使用done。我刚开始玩笑话?
    • 我使用了 try catch,因为显然如果我不这样做,有时它会跳转到 afterAll 那里返回错误。不打印先前的异常。所以我不知道发生了什么
    • 是不是因为我的内存快满了?我很难打开铬,因为我的内存使用率超过 92%。我尝试停止占用我大部分内存的 docker 服务,并且它起作用了。但我不知道
    • 我更新了我的答案,详细解释了异步/等待。请注意,它与 Jest 本身无关,而是与 async/await API 的工作方式有关。无论如何,我希望它对你有所帮助。让我知道是否足够清楚,以防万一接受答案?
    • 感谢async/await 的解释!有时候还是会报错,是不是我的内存太占地方了?有时上面的错误,有时我得到错误Jest did not exit one second after the test run has completed. This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.
    猜你喜欢
    • 2021-07-17
    • 1970-01-01
    • 2018-09-10
    • 2020-01-09
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 2022-11-06
    • 1970-01-01
    相关资源
    最近更新 更多