问题
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