playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] Is there a way to pause/debug tests on fail?

Open rhemfelt opened this issue 2 years ago • 11 comments

In TestCafe, there's a simple --debug-on-fail command line flag that automatically pauses the test if it fails, so you can troubleshoot and debug it. It is singularly one of the most used and useful command line flags for me in TestCafe, I run it with at least 95% of my test runs.

It doesn't seem that Playwright has this pause on fail option, making troubleshooting test failures a big pain. Trying to pinpoint exactly where in the test code it failed, then manually adding an await page.pause(); before that action or assertion, then rerunning each failed test, then manually performing the action that ostensibly triggered the initial failure, then going back and removing the await page.pause(); after you've finished debugging.

Is there any way (outside of VS Code) to automatically pause a test on failure? It's strange to me that this doesn't seem to be an option.

rhemfelt avatar Oct 16 '23 18:10 rhemfelt

This would save so much time. I really don't understand why is not the default behavior with --debug. See a related discussion that died here https://github.com/microsoft/playwright/issues/10132

When a test fails currently you need to:

  • find the file that failed
  • open the file
  • understand the code and which of the steps was failing by matching the steps in the ui against the code which is super hard
  • add await page.pause()
  • rerunning test

This happens very often and every time a minute or so is wasted.

aalexgabi avatar Jan 04 '24 15:01 aalexgabi

This feature would be very welcome! I tried to use the Break on (un)caught exceptions, but that triggers too much. I just want to break when an assertion fails, so I can debug whats going on and fix the test that way instead of using the trace viewer. It's very nice, but breaking in debug mode would be better :)

guido-visser avatar Feb 29 '24 10:02 guido-visser

Fully agree. I'm migrating my tests from TestCafe and I was surprised with this Playwright Debug behaviour. I do expect that I can debug my test on failure when I click on Debug test button. Otherwise I don't see any differences between just run the test or debug it.

MaksimStepanenko avatar Aug 20 '24 09:08 MaksimStepanenko

This feature request is over a year old now. 😔

The problem it suggests to fix is so painful that I would rather consider it a bug report! 😩

lolmaus avatar Nov 14 '24 15:11 lolmaus

CC @yury-s

lolmaus avatar Nov 14 '24 15:11 lolmaus

+1. Much needed.

A way around, not perfect, but you can at least stop / debug where the error occurs (after you know there's a problem at certain line of code / block):

async function withDebugger(fn: () => Promise<any>) {
  try {
    return await fn();
  } catch (error) {
    debugger;
    throw error;
  }
}

// Usage, within the test:
    await withDebugger(async () => {
      await page.getByLabel('Label').fill('Test Field 1');
    });

This will stop the test where the problem is.

Remember to run with Node's --inspect flag, and a Chrome debugger in the background.

elyran avatar Dec 23 '24 13:12 elyran

Up

guido-visser avatar Feb 20 '25 10:02 guido-visser

Still would be nice in 2025!

EDIT: This is possible using JUNIT 5 Testwatchers. Here's an example in Kotlin

class PlaywrightDebugExtension : TestWatcher {
    override fun testSuccessful(context: ExtensionContext) {
        val testInstance = context.testInstance.orElse(null)
        if (testInstance is PlaywrightBase) {
            closeBrowser(context, testInstance)
        }
    }

    override fun testFailed(context: ExtensionContext, cause: Throwable) {

        val testInstance = context.testInstance.orElse(null)
        if (testInstance is PlaywrightBase) {
            if (System.getenv("PIPELINE") != "true") {
                testInstance.log.error("Test failed: ${cause.message}")
                testInstance.log.info("Pausing browser for debugging...")
                testInstance.page.pause()
            } else {
                closeBrowser(context, testInstance)
            }
        }
    }

    private fun closeBrowser(
        context: ExtensionContext,
        testInstance: PlaywrightBase
    ) {
        val path = Paths.get("playwright/${context.displayName}.zip")
        testInstance.context.tracing().stop(
            StopOptions().setPath(path)
        )
        testInstance.context.close()
    }
}

tschuehly avatar Jul 03 '25 09:07 tschuehly

Yeah would love this. Currently need to run with --debug which just fails followed by then going into the specific test to add an await page.pause() manually right before the failing expect(). Would be great if there is a --debug --pause-on-fail combo.

florianschepp avatar Aug 27 '25 10:08 florianschepp