Skip to content

v0.44.0

Compare
Choose a tag to compare
@github-actions github-actions released this 24 Apr 10:44
· 535 commits to master since this release
14d80f6

k6 v0.44.0 is here! 🎉 This release includes:

  • A new k6/experimental/webcrypto module implementing (partially) the Web Crypto API specification.
  • A sampling option for the experimental tracing module.
  • Memory usage improvements.
  • Bug fixes and UX improvements.

Some highlights from the k6/experimental/browser module are:

  • locator.click is now asynchronous, which is a breaking change.
  • browserContext.addCookies has now been implemented.
  • browserType.Connect has been implemented so k6 can now connect to an already running Chrome/Chromium browser instance.
  • Web vitals are natively supported when working with the browser module.

Breaking changes

The browser module is still in an experimental stage, and therefore breaking changes are expected as we are improving the APIs to make them more user-friendly.

  • browser#790 Converted locator.click to async to have feature parity with page.click and elementHandle.click. Users must remember to work with promise.All and page.waitForNavigation() when a click action results in navigation.

    A locator.click action that doesn't result in navigation can be used like so:

    const tails = page.locator("input[value='Bet on tails!']");
    await tails.click(),

    A locator.click action that does result in a navigation can be used like so:

    const tails = page.locator("input[value='Bet on tails!']");
    await Promise.all([
      page.waitForNavigation(),
      tails.click(),
    ]);
  • browser#817 We've removed --no-sandbox from the default Chrome launch arguments. Now Chrome will launch with a sandbox, which is a more secure way of running the browser. If you are running tests under a root user, the browser will no longer launch unless the --no-sandbox argument is supplied. You can still pass this flag when launching a new Chrome instance using the args parameter on chromium.launch:

    const browser = chromium.launch({
      args: ['no-sandbox'],
    });
  • browser#844 Removed the exported version param from the root module. Users should from now on reference the k6 version instead of the browser module version.

  • browser#838 Removed the first meaningful paint metric. This metric is being deprecated across all the browsers, because the metric's definition relies on browser-specific implementation details, and we've now introduced web vitals in the browser module which is a reliable industry standard way to measure frontend performance. You can find more details here.

  • browser#843 Removed the build step from Github Actions. From this release onwards, no new standalone browser binaries will be built and available from the releases section. The latest version of the browser module will be available in the k6 binary which can be found in the k6 releases page.

New features

A new k6/experimental/webcrypto module implementing the Web Crypto API specification #3007

This release includes a new k6/experimental/webcrypto module partially implementing the Web Crypto API specification in k6.

Expand to see an example of the new functionality.

This example shows encrypting and decrypting of a "Hello, World!" string using AES-CBC algorithm.

import { crypto } from 'k6/experimental/webcrypto';

export default async function () {
  const key = await crypto.subtle.generateKey(
    {
      name: 'AES-CBC',
      length: 256,
    },
    true,
    ['encrypt', 'decrypt']
  );

  const encoded = stringToArrayBuffer('Hello, World!');
  const iv = crypto.getRandomValues(new Uint8Array(16));

  const ciphertext = await crypto.subtle.encrypt(
    {
      name: 'AES-CBC',
      iv: iv,
    },
    key,
    encoded
  );

  const plaintext = await crypto.subtle.decrypt(
    {
      name: 'AES-CBC',
      iv: iv,
    },
    key,
    ciphertext
  );

  console.log(
    'deciphered text == original text: ',
    arrayBufferToHex(plaintext) === arrayBufferToHex(encoded)
  );
}

function arrayBufferToHex(buffer) {
  return [...new Uint8Array(buffer)].map((x) => x.toString(16).padStart(2, '0')).join('');
}

function stringToArrayBuffer(str) {
  var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
  var bufView = new Uint16Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

You can see the list of currently supported APIs and algorithms in the project's README. Documentation for the module is available here.

Add sampling capabilities to the experimental tracing module #2886

This release adds sampling capabilities to the tracing module. You can now specify a sampling rate with the sampling option when initializing a Client, or in the tracing.InstrumentHTTP function.

browserContext.addCookies browser#760

Cookies can now be added to a BrowserContext and all new Pages created from this context will have the cookie assigned to them. Thanks @zucchinho for implementing this feature!

const context = browser.newContext()
context.addCookies([{name: 'myCookie', value: 'hello world', url: 'https://test.k6.io'}])
const page = context.newPage()

browserType.Connect browser#800

There are cases where the user may want to connect to a remote browser instance where they have more control over the browser lifecycle, such as when working in a resource bound environment. This feature enables users to connect to a manually started Chrome/Chromium browser instance. It's a simple case of replacing browser.launch with browser.connect and supplying the CDP url as the first argument. Not all launch options will work with connect since the browser instance should already have started prior to working with connect. Since we assume that the user had decided to take ownership of starting the browser, we have made browser.close a NOOP when working with browser.connect, so the user will need to close the browser themselves.

const browser = chromium.connect('ws://127.0.0.1:1234/devtools/browser/e3bb7e53-ad0f-46f3-ae89-a8416868f4ce')
const page = browser.newPage();

Web Vitals are now natively supported by the browser module browser#836 browser#847

Web vitals are the defacto way for developers to measure their frontend performance using the core metrics:

  • Largest contentful paint (LCP)
  • First input delay (FID)
  • Cumulative layout shift (CLS)

These measurements are now calculated for all tests without any additional work from your side. Simply run your test as you have been doing and you will be presented with the new metrics in the output. This is the output after running the examples/fillform.js script:

webvital_cumulative_layout_shift..........: avg=0        min=0        med=0        max=0        p(90)=0        p(95)=0
webvital_cumulative_layout_shift_good.....: 1       0.323332/s
webvital_first_contentful_paint...........: avg=278.86ms min=141.1ms  med=229.39ms max=466.1ms  p(90)=418.76ms p(95)=442.43ms
webvital_first_contentful_paint_good......: 3       0.969995/s
webvital_first_input_delay................: avg=300µs    min=200µs    med=300µs    max=399.99µs p(90)=379.99µs p(95)=389.99µs
webvital_first_input_delay_good...........: 2       0.646663/s
webvital_interaction_to_next_paint........: avg=16ms     min=16ms     med=16ms     max=16ms     p(90)=16ms     p(95)=16ms
webvital_interaction_to_next_paint_good...: 1       0.323332/s
webvital_largest_content_paint............: avg=303.6ms  min=141.1ms  med=303.6ms  max=466.1ms  p(90)=433.6ms  p(95)=449.85ms
webvital_largest_content_paint_good.......: 2       0.646663/s
webvital_time_to_first_byte...............: avg=205.23ms min=104.79ms med=188.39ms max=322.5ms  p(90)=295.67ms p(95)=309.08ms
webvital_time_to_first_byte_good..........: 3       0.969995/s

You may have noticed other metrics in there too. We rely on the web-vitals JS library which exposes a few more metrics, so we've left them in for you to experiment with. You can find more details on all the browser module metrics in our documentation.

You will no longer see browser_first_contentful_paint in the summary, and instead you can work with webvital_first_contentful_paint.

UX improvements and enhancements

  • #2906 Added multiple date-time formats for CSV output. Thanks, @Azanul!
  • #2916 k6 started to show the actual binary's name in the usage help. Thanks, @ariasmn!
  • #2942 Reference 'k6 cloud' instead of 'Load Impact' in docs and errors.
  • #2985 Added support of async functions for setup and handleSummary.
  • #2901 Added a warning when the number of time series exceeds 100 000, which could lead to potential out-of-memory issues.
  • #2997 Added a new exit code (109), used on a go panic.
  • browser#788 Updated the browser readme to highlight that it is now a module in k6.
  • browser#803 Users are now warned if the browser.close method is called more than once.
  • browser#820 Added error handling to wildcard selectors, which cleans up the error output in the terminal.
  • browser#848 Multiple k6 instances can now connect to one browser to run concurrent tests. This update empowers high-concurrency browser testing with multiple VUs and instances. Using the new browserType.Connect API, users can now connect to an existing browser instance and execute concurrent tests, which was not possible previously.

Bug fixes

  • #2984 Fixed wrongly assigned HTTP POST and PUT methods for the tracing.instrumentHTTP. Thanks, @marcin-maciej-seweryn!
  • #2928 Handled a new behavior of filepath.Join on windows with go1.20, which could cause issues for the k6 archive and k6 cloud commands.
  • #2915 Fixed check that could return incorrect values for some cases with many preallocated VUs.
  • #2953 Fixed active VU reporting by arrival-rate executors.
  • #3006 xk6-websockets updated to v0.2.0 which fixes a lock up of the whole k6.
  • #3023 Fixed Trend.Max's support of negative values.
  • browser#781 Fixed mapping of response object's function from jSON to json.
  • browser#779 Cleared Zombie processes on panic.
  • browser#834 Fixed page.close so that it closes the current page and not the whole browser context.

Maintenance and internal improvements

Improved the per-VU buffer pool #2879

Improved the per-VU buffer pool which should greatly reduce memory usage, at a minor expense of higher CPU usage and lower request throughput. In some cases, this change can reduce memory usage up to 50%.

Thanks to @davidpst for the contribution!

Other minor changes in this release:

  • #3004 Changed eventloop.WaitOnRegistered to execute all scheduled callbacks.
  • #2881 Refactored how modules are loaded. This is a preparation for the upcoming ESM support.
  • #2920 Updated Go version that we use for k6 compilation to 1.20.x. The docker image is also updated to use alpine:3.17.
  • #2986 Refactored goja's isNullish to be a part of js/common.
  • #2960 Refactored sirupsen/logrus usage.
  • #2999 Directly embed lib.TestPreInitState in js/common.InitEnvironment.
  • #2892 Added z/OS build flags for IBM z/OS compatibility. Thanks, @msradam!
  • #2833 Fixed detected memory leaks.
  • #2931, #2940, #2895, #3002 Updated k6's dependencies. Added goja's generator support.
  • #2947, #2943, #2946, #3009, #3012, #2894 Tests' fixes, refactoring, and improvements.
  • #2891, #2921, #2923, #2990, #2995, #3016, #2989 Linters and formatting fixes.
  • #3005 The samples catalog was renamed to examples.
  • browser#776 Fixed a test for preset flags for Chrome on macOS.
  • browser#782, browser#783, browser#826 Fixed and refactored the Go-JS mapping.
  • browser#797, browser#832 Fixed multi browser close.
  • browser#796, browser#810 Refactored browserContext.SetExtraHTTPHeaders to work with errors and ErrFatal.
  • browser#798, browser#799 Added more tests for the Go-JS mapping layer.
  • browser#802 Added a helper to assert on the logs and dump the logs for easier debugging.
  • browser#807 Fixed incorrect keyboard key code on up/down key presses.
  • browser#819 Browser.Launch now transitions to Browser.Connect when a CDP URL is provided in an environment variable.
  • browser#821, browser#824, browser#830 Upgraded dependencies and fixed breaking changes.