---
next_cursor: eyJzY29yZSI6MCwic2VxIjoxNDg1LCJzaW5jZSI6bnVsbCwidG9vbCI6Ims2IiwidiI6MX0
has_more: true
next: https://sincecutoff.com/v1/changes.md?tool=k6&score=0&cursor=eyJzY29yZSI6MCwic2VxIjoxNDg1LCJzaW5jZSI6bnVsbCwidG9vbCI6Ims2IiwidiI6MX0
items: 10
---
# sincecutoff.com changes: k6

## k6 adds an opt-in machine-readable summary (k6, 2026-01-05)
Published 2026-10-19
- slug: k6-adds-an-opt-in-machine-readable-summary-7b0b5264d322
- score: 0.98

How to use it:

When exporting a k6 end-of-test summary in structured form, enable the machine-readable format and write it with `--summary-export` or `handleSummary()`.

Examples:

```
k6 run script.js --new-machine-readable-summary --summary-export=summary.json
```

```
K6_NEW_MACHINE_READABLE_SUMMARY=true k6 run --summary-export summary.json script.js
```

```
export function handleSummary(data) { return { 'summary.json': JSON.stringify(data) }; }
```

- why_it_matters: Export a k6 test run summary in a structured format for a CI pipeline or custom analysis script.
- sources: <https://github.com/grafana/k6/releases/tag/v1.5.0>, <https://github.com/grafana/k6/blob/v1.5.0/internal/cmd/runtime_options.go>, <https://grafana.com/docs/k6/latest/results-output/end-of-test/custom-summary/>, <https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/>
- gotchas: "Version: v1.5.0"; "Availability: Currently opt-in; the format will become the default in k6 v2."; "--new-machine-readable-summary: Enables the new machine-readable summary format; used for `--summary-export` and as the `handleSummary()` argument."; "K6_NEW_MACHINE_READABLE_SUMMARY: Environment variable that enables the machine-readable format; set to a boolean value such as `true`."; "--summary-export <filename>: For `k6 run`, saves the end-of-test summary report to a JSON file; `<filename>` is the output path."; "handleSummary(data): End-of-test callback receiving the aggregated summary object; return a map whose string keys are `stdout`, `stderr`, or file paths and whose values are strings or `ArrayBuffer`."; "Prerequisite: The documented `--summary-export` command is available with `k6 run`."; "Prerequisite: The machine-readable format was introduced in k6 v1.5.0; the v1.5.0 release note says it is opt-in."; "The format is currently opt-in."; "Docs conflict: Current options documentation discourages `--summary-export` and recommends `handleSummary()` for flexible exports; it still documents the flag and its JSON output. This guidance is from newer documentation than v1.5.0. https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/"

## k6/browser locator.pressSequentially() types with keyboard events (k6, 2026-01-05)
Published 2026-10-19
- slug: k6-browser-locator-presssequentially-types-with-keyboard-events-038fcfc1c573
- score: 0.98

How to use it:

When testing input behavior that responds to individual keystrokes, use `locator.pressSequentially()` to type characters and fire keyboard events. Set `delay` in milliseconds to test handlers that depend on time between keystrokes.

Examples:

```
import { browser } from 'k6/browser';

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

export default async function () {
  const page = await browser.newPage();
  try {
    await page.goto('<URL>');
    await page.locator('<input selector>').pressSequentially('<text>', { delay: 100 });
  } finally {
    await page.close();
  }
}
```

- why_it_matters: Test a browser input that reacts to each keystroke, such as autocomplete or per-character validation.
- before: Use `locator.type()` for gradual typing without keyboard events, or `locator.fill()` for simple form filling.
- sources: <https://github.com/grafana/k6/releases/tag/v1.5.0>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/locator/presssequentially/>
- gotchas: "Version: v1.5.0"; "text (required): String to type into the focused element character by character."; "options.delay: Milliseconds to wait between key presses; defaults to 0."; "options.noWaitAfter: If true, do not wait for navigation caused by the action to complete; defaults to false."; "options.timeout: Maximum time in milliseconds; defaults to 30000, or the BrowserContext/Page default timeout. Use 0 to disable."; "A configurable delay between keystrokes is supported."; "Docs conflict: The latest documentation shows k6 v2.3.x, newer than the card's v1.5.0; version-specific differences were not established."

## k6/browser page.waitForEvent() synchronizes on events (k6, 2026-01-05)
Published 2026-10-19
- slug: k6-browser-page-waitforevent-synchronizes-on-events-a05900ed5e02
- score: 0.99

How to use it:

When a browser test must wait for a console, request, or response event, call `page.waitForEvent(event[, optionsOrPredicate])` before triggering the event and await its promise before continuing.

Examples:

```
const msgPromise = page.waitForEvent('console', msg => msg.text().includes('hello'));
await page.evaluate(() => console.log('hello world'));
const msg = await msgPromise;
```

```
const resPromise = page.waitForEvent('response', {
  predicate: res => res.url().includes('/api/data'),
  timeout: 5000,
});
await page.click('button#fetch-data');
const res = await resPromise;
```

- why_it_matters: Write a browser test that proceeds after a specific console message or matching response is observed.
- sources: <https://github.com/grafana/k6/releases/tag/v1.5.0>, <https://github.com/grafana/k6/blob/v1.5.0/release%20notes/v1.5.0.md>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/waitforevent/>
- gotchas: "Version: v1.5.0"; "event (required): Event name; supported values are `console`, `request`, and `response."; "optionsOrPredicate: A predicate function or options object; the two forms are alternatives."; "options.predicate: Function receiving the event object; return true when it is the expected event."; "options.timeout: Maximum wait in milliseconds; default 30000, or 0 to disable. BrowserContext or Page `setDefaultTimeout` can override the default."; "The method blocks the caller until the specified event is captured; with a predicate, it waits for an event satisfying that predicate."

## k6/browser adds frameLocator() (k6, 2026-02-10)
Published 2026-10-19
- slug: k6-browser-adds-framelocator-bd6e7eef3129
- score: 0.98

How to use it:

When a k6 browser test needs to interact with iframe content, call `frameLocator(selector)` with a selector that resolves to the iframe. Chain another `frameLocator()` for nested frames, then use `locator()` to target and interact with elements inside.

Examples:

```
import { browser } from 'k6/browser';

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

export default async function () {
  const page = await browser.newPage();
  try {
    await page.goto('<URL>');
    const frame = page.frameLocator('<iframe-selector>');
    await frame.locator('<element-selector>').click();
    const nested = page.frameLocator('<outer-iframe-selector>')
      .frameLocator('<inner-iframe-selector>');
    await nested.locator('<nested-element-selector>').click();
  } finally {
    await page.close();
  }
}
```

- why_it_matters: Interact with elements inside an iframe while testing a web application with k6 browser.
- sources: <https://github.com/grafana/k6/releases/tag/v1.6.0>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/locator/framelocator/>
- gotchas: "Version: v1.6.0"; "selector (required): String selector that resolves to an iframe element; used by `frameLocator(selector)` to return a FrameLocator for that iframe."; "Prerequisite: Configure a browser scenario with a browser type such as `chromium` and import `browser` from `k6/browser`."

## k6/browser adds requestfinished and requestfailed event handlers (k6, 2026-02-10)
Published 2026-10-19
- slug: k6-browser-adds-requestfinished-and-requestfailed-event-handlers-40d1758c06bc
- score: 0.93

How to use it:

When debugging a k6 browser test, register `requestfailed` and `requestfinished` listeners on the page before navigation to observe failed and completed network requests.

Examples:

```
import { browser } from 'k6/browser';

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

export default async function () {
  const page = await browser.newPage();
  page.on('requestfailed', (request) => console.log(`Request failed: ${request.url()}`));
  page.on('requestfinished', (request) => console.log(`Request finished: ${request.url()}`));
  await page.goto('<URL>');
  await page.close();
}
```

- why_it_matters: Monitor successful and failed network requests while debugging a k6 browser test.
- sources: <https://github.com/grafana/k6/releases/tag/v1.6.0>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/on/>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/request/>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/>
- gotchas: "Version: v1.6.0"; "event (required): Event name: `requestfailed` for requests that fail to reach the server; `requestfinished` for requests that successfully complete."; "handler (required): Callback invoked when the event is emitted; receives the corresponding Request object."; "request.url(): Returns the request URL; usable in the event handler for logging."; "Prerequisite: Use a current k6 version to work with the browser module."; "`requestfailed` fires for request failures such as network errors or aborts; `requestfinished` fires when a request completes successfully."

## k6/browser Page adds goBack() and goForward() (k6, 2026-02-10)
Published 2026-10-19
- slug: k6-browser-page-adds-goback-and-goforward-8323f0867bd6
- score: 0.96

How to use it:

When a k6 browser script needs to test session history, use `page.goBack()` or `page.goForward()` after navigation; await the call and pass optional `{ timeout, waitUntil }` settings as needed.

Examples:

```
import { browser } from 'k6/browser';

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

export default async function () {
  const page = await browser.newPage();
  try {
    await page.goto('<first-url>');
    await page.goto('<second-url>');
    await page.goBack({ timeout: 30000, waitUntil: 'load' });
    await page.goForward();
  } finally {
    await page.close();
  }
}
```

- why_it_matters: Test browser history navigation in a k6 browser script.
- sources: <https://github.com/grafana/k6/releases/tag/v1.6.0>, <https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/goback/>, <https://grafana.com/docs/k6/latest/using-k6-browser/running-browser-tests/>, <https://grafana.com/docs/k6/latest/using-k6-browser/>
- gotchas: "Version: v1.6.0"; "options: Options object for the history navigation call; defaults to null."; "options.timeout: Maximum operation time in milliseconds; defaults to 30000. Set to 0 to disable the timeout."; "options.waitUntil: Navigation success event; defaults to `load`. Allowed values: `domcontentloaded`, `load`, `networkidle`. Docs caution that `networkidle` may never fire on busy sites."; "Prerequisite: A browser scenario must specify an executor and set `options.browser.type` to `chromium`."; "Prerequisite: Install k6 and a Chromium-based browser, or use a Docker image with Chromium built in."; "The methods support optional timeout and `waitUntil` parameters."

## k6 Cloud commands support a configurable default stack (k6, 2026-02-10)
Published 2026-10-19
- slug: k6-cloud-commands-support-a-configurable-default-stack-f75ad1d847d4
- score: 0.97

How to use it:

When running a Grafana Cloud test, log in with a stack to save it as the default, or set a stack for that run with `K6_CLOUD_STACK_ID` or `options.cloud.stackID`.

Examples:

```
k6 cloud login
```

```
k6 cloud login --token <YOUR_API_TOKEN> --stack <YOUR_STACK_URL_OR_SLUG>
```

```
K6_CLOUD_STACK_ID=<YOUR_STACK_ID> k6 cloud run <SCRIPT.js>
```

- why_it_matters: Run a test in Grafana Cloud using the configured default stack or a stack selected for that run.
- before: Users had to specify the project ID for every test run.
- sources: <https://github.com/grafana/k6/releases/tag/v1.6.0>, <https://grafana.com/docs/k6/latest/reference/cloud-commands/>, <https://grafana.com/docs/grafana-cloud/observe-and-act/testing/k6/author-run/tokens-and-cli-authentication/?mdm=referral&plcmt=footer&src=joyk.com>, <https://github.com/grafana/k6/blob/v1.6.0/cloudapi/config.go>
- gotchas: "Version: v1.6.0"; "--token <YOUR_API_TOKEN>: API token for authentication; used with `--stack` for non-interactive login."; "--stack <YOUR_STACK_URL_OR_SLUG>: Stack URL or slug where cloud commands run by default."; "K6_CLOUD_STACK_ID=<YOUR_STACK_ID>: Environment variable selecting the stack by ID for cloud commands."; "options.cloud.stackID: Stack ID selected for the run; available in k6 v1.6.0 and later."; "options.cloud.projectID: Project ID for the cloud run."; "Prerequisite: Authenticate with a Grafana Cloud k6 API token and configure a stack to run cloud commands."; "A stack slug or stack id is used to determine which default project to use when one is not explicitly provided."; "If `projectID` does not belong to the configured stack, the run throws an error."; "Stack information will become mandatory to run a test in k6 v2."; "Docs conflict: Current k6 documentation says every cloud subcommand requires a configured stack; current release notes state stack is mandatory in k6 v2. The official v1.6.0 source documents stackID and projectID fields, but current documentation may describe newer behavior."

## k6 deps analyzes script and archive dependencies (k6, 2026-02-10)
Published 2026-10-19
- slug: k6-deps-analyzes-script-and-archive-dependencies-175f158dbc81
- score: 0.97

How to use it:

When you need to identify script or archive dependencies for an auto-resolved build, run `k6 deps <script-or-archive>`; add `--json` for programmatic output. The command reports dependencies found through imports and “use” directives, but does not follow dynamic `require()` calls.

Examples:

```
k6 deps <script.js>
```

```
k6 deps --json <script.js>
```

```
k6 deps <archive.tar>
```

- why_it_matters: Inspect a script or archive to identify extension dependencies needed to build a binary with auto extension resolution.
- sources: <https://github.com/grafana/k6/releases/tag/v1.6.0>, <https://grafana.com/docs/k6/latest/release-notes/v1.6.0/>, <https://grafana.com/docs/k6/latest/using-k6/k6-deps-command/>
- gotchas: "Version: v1.6.0"; "<script> (required): Script or archive to analyze."; "--json: Output dependency information in JSON; default output is human-readable."; "Dependency analysis accounts for imports, not dynamic `require()` calls."

## k6 run supports a dependency manifest for default version constraints (k6, 2026-02-10)
Published 2026-10-19
- slug: k6-run-supports-a-dependency-manifest-for-default-version-constraints-1acb14c9aea2
- score: 0.94

How to use it:

When an imported dependency has no version constraint in the script, set `K6_DEPENDENCIES_MANIFEST` to a JSON map of dependency names to constraints and run the script. The manifest supplies a default only for imported dependencies without an explicit version or `use k6 with` directive.

Examples:

```
K6_DEPENDENCIES_MANIFEST='{"k6/x/faker": ">=v0.4.4"}' k6 run <script.js>
```

- why_it_matters: Run a script with imported dependencies that lack explicit version constraints and need manifest-specified constraints.
- before: An imported dependency without an explicit version defaults to `"*"`.
- sources: <https://github.com/grafana/k6/releases/tag/v1.6.0>
- gotchas: "Version: v1.6.0"; "K6_DEPENDENCIES_MANIFEST: Environment variable containing a JSON object whose keys are dependency names and whose values are version constraints; it replaces the default `*` constraint when the imported dependency has no version defined in script pragmas."; "dependency name (JSON key) (required): Name of a dependency imported by the script, such as `k6/x/faker`; entries do not affect dependencies the script does not import."; "constraint (JSON value) (required): Version constraint to apply to that imported dependency when the script does not define its version using pragmas."; "k6 run <script.js> (required): Runs the script with the manifest environment variable set in the invocation."; "The manifest does not change anything for a dependency that is not imported by the script."; "The manifest supplies defaults when a dependency has no version defined in the script using pragmas."

## k6 automatically resolves missing subcommand extensions (k6, 2026-03-25)
Published 2026-10-19
- slug: k6-automatically-resolves-missing-subcommand-extensions-65168ef8914e
- score: 0.95

How to use it:

If the subcommand extension is missing from the current k6 binary and is registered in the extension catalog, run `k6 x httpbin`; k6 provisions the extension and executes it. For community extensions, set `K6_ENABLE_COMMUNITY_EXTENSIONS=true`.

Examples:

```
k6 x httpbin
```

```
K6_ENABLE_COMMUNITY_EXTENSIONS=true k6 x httpbin
```

- why_it_matters: Run a subcommand extension that is not included in the current k6 binary.
- before: Previously, using extension subcommands required manually building a custom k6 binary with xk6.
- sources: <https://github.com/grafana/k6/releases/tag/v1.7.0>, <https://grafana.com/docs/k6/latest/extensions/create/subcommand-extensions/>
- gotchas: "Version: v1.7.0"; "x httpbin (required): Invokes the registered `httpbin` subcommand extension in the `k6 x` namespace."; "K6_ENABLE_COMMUNITY_EXTENSIONS: Set to `true` to use community extensions."; "Prerequisite: Use k6 v1.7.0 or later for automatic resolution of subcommand extensions."; "Prerequisite: The extension must be registered in the k6 extension catalog. Community extensions require `K6_ENABLE_COMMUNITY_EXTENSIONS=true`."; "Automatic resolution applies when the subcommand extension is not included in the current binary."

Next: https://sincecutoff.com/v1/changes.md?tool=k6&score=0&cursor=eyJzY29yZSI6MCwic2VxIjoxNDg1LCJzaW5jZSI6bnVsbCwidG9vbCI6Ims2IiwidiI6MX0
Save `next_cursor`; next visit, pass it to get only what was published since.
<!-- end of page -->
