Unable to catch expect() failures with try/catch in k6 - test aborts instead of throwing

Hi everyone,

I’m experimenting with the k6-testing library and noticed that expect() failures cannot be caught with a normal try/catch. Even when wrapped properly, the test aborts instead of allowing execution to continue.

Here’s a minimal reproducible example:

import { browser } from "k6/browser";
import { expect } from "https://jslib.k6.io/k6-testing/0.5.0/index.js";

export const options = {
  scenarios: {
    ui: {
      executor: "shared-iterations",
      iterations: 1,
      options: { browser: { type: "chromium" } },
    },
  },
};

export default async function () {
  const ctx = await browser.newContext();
  const page = await ctx.newPage();

  console.log("STEP 1: goto");
  await page.goto("https://example.com");

  console.log("STEP 2: about to run expect (inside try/catch) …");
  try {
    await expect(page.locator("#definitely-not-here")).toBeVisible({ timeout: 1000 });
    console.log("SHOULD-NOT-SEE: expect passed");
  } catch (err) {
    console.warn("SHOULD-SEE (but won’t): caught expect error:", err?.message);
  }

  console.log("STEP 3: cleanup");
  await page.close();
  await ctx.close();
}

Output:

INFO[0000] STEP 1: goto                                  source=console
INFO[0000] STEP 2: about to run expect (inside try/catch) …  source=console
ERRO[0002] test aborted: 

   Error: expect(locator).toBeVisible()
      At: /Users/DylanPaulson/Documents/veeva/perf-test/testing/expect.js:25:67

Expected: visible
Received: hidden
Call log: 
  - expect.toBeVisible with timeout 1000ms
  - waiting for locator

Filename: expect.js
    Line: 25

 at O (https://jslib.k6.io/k6-testing/assert.ts:54:20(32)) 

You never see the “caught expect error” log, confirming that the try/catch doesn’t intercept the failure, instead the whole test aborts.


What I’m trying to do
I want to gracefully handle failed expectations inside test logic.

For example, I’d like to:

  • Catch the failure,
  • Update a variable (e.g., isFailed = true),
  • Record that as a check() or custom metric,
  • Then continue execution for cleanup or additional steps.

What I’ve tried

I’m aware of the softMode option for expect(), but it only logs the pass/fail result to the console and doesn’t return a value or throw, so I can’t use it to set variables programmatically.


Question

Is there currently any way to catch or handle expect() failures programmatically, without the test aborting, or is this behavior by design?

If not, would adding support for returning structured results (or allowing normal exceptions to bubble up) be something that could be considered?