Jest-js Pupetter等待puppeteer启动newPage返回未定义

时间:2019-02-11 04:32:23

标签: jestjs puppeteer

我想使用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自动完成。我以为是杰斯特。不能使用吗?

1 个答案:

答案 0 :(得分:1)

尝试将fail("SETUP FAILED:\n"+e)调用更改为console.log("SETUP FAILED:\n"+e),让我们知道它记录了什么。

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

更多注意事项:

  • 您不需要进行done()调用,beforeAll函数是异步的,并且您等待每一个Puppeteer调用,因此...该函数自行终止,无需使用{ {1}}个电话。甚至将其从传递的参数中删除

  • 您致电done(),但在哪里定义?

  • 删除所有内容中的大fail,如果出现错误,则测试会自动失败,并会提供有用的见解;另外try/catch不会给您带来任何好处,也不会使测试更加冗长

让我知道它是否有帮助

更新

评论中的另一个问题是

  

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

好吧,我从头开始:

'beforeAll'函数只是一个常规的JS函数

try/catch

因此,如果您要在其中制作一些异步内容

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

它不知道应该等待什么,这就是为什么您可以利用beforeAll(() => { setTimeout(() => { // ... }, 1000); } 函数的原因

done

因此,在您手动调用beforeAll((done) => { setTimeout(() => { done(); }, 1000); } 函数本身之前,Jest不会将其视为“完成”。 承诺的价值相同

done

或某些应许串联

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

我们可以缩短它

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

异步/等待 添加了beforeAll((done) => { yourFunctionThatReturnsAPromise(() => anotherPromise()) .then(() => anotherPromise()) .then(() => done()); } 是为了更好地管理Promise链,让我们看看如何转换后一个功能

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

这样做会自动等待每个诺言,并且我们告诉JS我们的函数是异步的,并且它会自动等待诺言完成,然后再考虑我们的函数完成。由于它会自动等待,因此我们现在可以删除beforeAll用途

done

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

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

并将其转换为原始版本

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函数

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的承诺)被解决后才会结束。