Since nightwatch 0.6.x allows to display browser logs , I'm trying to implement a global afterEach hook that displays the browser logs after a test case finishes. When a test case finishes because of an assertion error, the session is terminated and it becomes impossible to execute the sessionLog command.
It would be convenient to keep the session alive while the afterEach hooks are executed.
Thanks for the great job!
You can use verify instead of assert, that won't terminate the session in
case of failure.
On Sunday, April 12, 2015, Enrique [email protected] wrote:
Since nightwatch 0.6.x allows to display browser logs , I'm trying to
implement a global afterEach hook that displays the browser logs after a
test case finishes. When a test case finishes because of an assertion
error, the session is terminated and it becomes impossible to execute the
sessionLog command.It would be convenient to keep the session alive while the afterEach hooks
are executed.Thanks for the great job!
—
Reply to this email directly or view it on GitHub
https://github.com/beatfactor/nightwatch/issues/413.
But the session should terminate. I don't want the test to keep running after an assertion or a waitForElement[Visible|Present] fails. The correct behavior is to stop and go to the next suite. But before that happens I'd like to have a more detailed report of the environment state by displaying the selenium logs.
I see, did you try with a testsuite-based after hook? I think that one should restart the session.
So, to summarize, it is possible to achieve this starting with v0.6.5. Here's how:
1) Set end_session_on_fail property to false in your test_settings;
'@endSessionOnFail' : false in the current test suite2) In your afterEach, call the sessionLog and the end to end the session:
afterEach : function(client, done) {
client.sessionLog(function(result) {
console.log(result);
}).end(function() {
done();
});
}
Feel free to re-open if you think it's incomplete or wrong.
this approach doesn't work for me with nightwatch v0.9.10
simple example test that should fail:
module.exports = {
'step one' : function (browser) {
browser
.url('http://www.google.com')
.waitForElementVisible('body', 1000)
.setValue('input[type=text]', 'nightwatch')
.waitForElementVisible('button[name=btnG]', 1000)
},
'step two' : function (browser) {
browser
.click('button[name=btnG]')
.pause(1000)
.verify.containsText('#main', 'asdfghjkl;;lkjhgffdsa')
.end();
}
};
@beatfactor I think that ending the selenium session between each test as a default behaviour is definitely the right thing to do, but that doesn't mean we should clear the sessionId value.
Decoupling sessionId from the running session would produce the expected results in my case (#1383) since, naturally, a developer would assume that sessionId always refers to the active session or the one that has last ended (if inside an afterEach block).
This, I believe, wouldn't break any existing mechanics, since inside an afterEach block sessionId would always refer to the sessionId of the last running test and the moment that afterEach block finishes, a beforeEach (and inside the actual test) would always refer to the session that is about to be run/running.
Maybe requires a bit of tricksiness if afterEach and beforeEach are running asynchronously but I imagine making a sessionId() function (which checks state) instead of a hard coded variable would be the best way around that. Calling the function would always return what's expected, internal id's could be as simple as lastRunSessionId and currentSessionId, and if if the calling function is a test or beforeEach we use current and if it's from inside an afterEach block we use last run.
Thoughts?
Most helpful comment
@beatfactor I think that ending the selenium session between each test as a default behaviour is definitely the right thing to do, but that doesn't mean we should clear the
sessionIdvalue.Decoupling
sessionIdfrom the running session would produce the expected results in my case (#1383) since, naturally, a developer would assume that sessionId always refers to the active session or the one that has last ended (if inside an afterEach block).This, I believe, wouldn't break any existing mechanics, since inside an afterEach block
sessionIdwould always refer to the sessionId of the last running test and the moment that afterEach block finishes, a beforeEach (and inside the actual test) would always refer to the session that is about to be run/running.Maybe requires a bit of tricksiness if afterEach and beforeEach are running asynchronously but I imagine making a
sessionId()function (which checks state) instead of a hard coded variable would be the best way around that. Calling the function would always return what's expected, internal id's could be as simple aslastRunSessionIdandcurrentSessionId, and if if the calling function is a test or beforeEach we use current and if it's from inside an afterEach block we use last run.Thoughts?