Online Training: Web test automation with CodeceptJS. Sign up now!

How to Implement "Pause On Fail"

Hi @davert,

ask asked in Slack I tried to implement pause() on fail with the following code as plugin:

const event = require("codeceptjs").event;

module.exports = function() {
  event.dispatcher.on(event.step.failed, async function(step, error) {
    console.log("--- Failed step ---");
    await pause();
  });
};

The output is the following:

CodeceptJS v2.3.3
Using test root "/Users/paul/projects/ds-e2e-test-automation/configs"
Helpers: WebDriver, Api, REST, CustomActions
Plugins: screenshotOnFail, pauseOnFail

Pause on --
    [1] Starting recording promises
    Emitted | suite.before ([object Object])
  Fail @run
    Emitted | test.before ([object Object])
    Emitted | test.start ([object Object])
    Emitted | step.before (I see "Fail")
    Emitted | step.after (I see "Fail")
    Emitted | step.start (I see "Fail")
    I see "Fail"
    › [SmartWait (5000ms)] Locating body in 5000
    [1] Error | Error
    Emitted | step.failed (I see "Fail")
--- Failed step ---
    Emitted | step.finish (I see "Fail")
    [1] Error | Error
    [1] Starting <teardown> session
    Emitted | test.failed ([object Object])
    Emitted | test.finish ([object Object])
    [1] <teardown> Stopping recording promises
 › <screenshotOnFail> Test failed, saving screenshot
 › Screenshot has been saved to /Users/paul/projects/test-automation/output/Fail_@run.failed.png
    [1] <teardown> Starting <pause> session
 Interactive shell started
 Use JavaScript syntax to try steps in action
 - Press ENTER to run the next step
 - Press TAB twice to see all available commands
 - Type exit + Enter to exit the interactive shell
 I.  ✖ FAILED in 567ms

    [2] Starting recording promises
    Emitted | test.after ([object Object])
    Emitted | suite.after ([object Object])

-- FAILURES:

  1) Pause on
       Fail @run:
     expected web page to include "Fail"
  
  Scenario Steps:
  
  - I.see("Fail") at Test.Scenario (scenarios/Fail_test.js:7:7)
  
  


  FAIL  | 0 passed, 1 failed   // 3s
    Emitted | global.result ([object Object])
    Emitted | global.after ([object Object])
asd
 ERROR  Cannot read property 'then' of undefined
 I.

So basically what happens is, that the browser is closed before pause() is called.

How can I pause() the test scenario before the browser closes?

Thanks!

/cc @christian_wolf

1 Like

You forgot to synchronize steps via recorder.

  event.dispatcher.on(event.step.failed, function(step, error) {
    console.log("--- Failed step ---");
    recorder.add('starting pause', pause);
  });

If this will work for you, please make a pull request introducing pauseOnFail as a plugin. That would be really nice!

1 Like

Yeah, that would be nice indeed! :slight_smile:

@davert unfortunately the test execution does not pause:

const { event, recorder, output } = require("codeceptjs");

module.exports = function() {
  event.dispatcher.on(event.step.failed, async function(step, error) {
    output.debug("--- On failed step ---");
    recorder.add("starting pause", pause);
  });
};

Verbose output:

Pause on --
    [1] Starting recording promises
    Emitted | suite.before ([object Object])
  Fail @run
    Emitted | test.before ([object Object])
    Emitted | test.start ([object Object])
    Emitted | step.before (I see "Fail")
    Emitted | step.after (I see "Fail")
    Emitted | step.start (I see "Fail")
    I see "Fail"
    › [SmartWait (5000ms)] Locating body in 5000
    [1] Error | Error
    Emitted | step.failed (I see "Fail")
    › --- On failed step ---
    Emitted | step.finish (I see "Fail")
    [1] Error | Error
    [1] Starting <teardown> session
    Emitted | test.failed ([object Object])
    Emitted | test.finish ([object Object])
    [1] <teardown> Stopping recording promises
 › <screenshotOnFail> Test failed, saving screenshot
 › Screenshot has been saved to /Users/paul/projects/test-automation/output/Fail_@run.failed.png
  ✖ FAILED in 366ms

    [2] Starting recording promises
    Emitted | test.after ([object Object])
    Emitted | suite.after ([object Object])

Looks for me linke that that recorder.add() is executed to late. Any idea how to make this work?

Ok, I will try to implement that myself

2 Likes