How to make nightmare forcefully timeout

跟風遠走 提交于 2020-01-06 08:21:09

问题


As the title implies I am trying to make my script timeout forcefully, specifically if a condition (that returns done()) isn't met.

Here is some code:

import * as Nightmare from "nightmare";

describe("Login Page", function() {
  this.timeout("30s");

  let nightmare = null;
  beforeEach(() => {
    nightmare = new Nightmare({ show: true });
  });

  let pageUrl;

  describe("give correct details", () => {
    it("should log-in, check for current page url", done => {
      nightmare
        .goto(www.example.com/log-in)
        .wait(5000)
        .type(".input[type='email']", "username")
        .type(".input[type='password']", "password")
        .click(".submit")
        .wait(3000)
        .url()
        .exists(".navbar")
        .then(function(result) {
          if (result) {
            done();
          } else {
            console.log("failure");
                // I want it to timeout here
          }
        })
        .catch(done);
    })
        .end()
        .then(url => {
          pageUrl = url;
          console.log(pageUrl);
        })
  });
});

If I have any other mistakes in my code feel free to let me know.


回答1:


You can use Promise.race() to implement a timeout. I don't know your testing code so I'll show just the inner part that gives you a timeout on the nightmare request and you can insert that into your test framework.

// utility function that returns a rejected promise after a timeout time
function timeout(t, msg) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            reject(new Error(msg));
        }, t);
    });
}

Promise.race([
    nightmare
        .goto(www.example.com / log - in )
        .wait(5000)
        .type(".input[type='email']", "username")
        .type(".input[type='password']", "password")
        .click(".submit")
        .wait(3000)
        .url()
        .exists(".navbar")
        .end()
    , timeout(5000, "nightmare timeout")
]).then(result => {
    // process successful result here
}).catch(err => {
    // process error here (could be either nightmare error or timeout error)
});

The concept here is that you create a race between the promise from your nightmare request and a promise from the timeout. Whichever one resolves or rejects first wins and causes the end of the promise processing. If the Promise.race(...).then() handler triggers, then it's because your nightmare request finished before the timeout. If the Promise.race(...).catch() handler fires, then it's because either the nightmare request failed or you hit the timeout. You can tell which it is by looking at the error object you get with the reject.

Note, there are also all sorts of timeout options built into nightmare as described in the doc here. You may also find one of those built-in options suits whatever the exact purpose of your timeout is.



来源:https://stackoverflow.com/questions/50033704/how-to-make-nightmare-forcefully-timeout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!