release notes/v0.44.0.md
k6 v0.44.0 is here! 🎉 This release includes:
k6/experimental/webcrypto module implementing (partially) the Web Crypto API specification.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.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.
k6/experimental/webcrypto module implementing the Web Crypto API specification #3007This release includes a new k6/experimental/webcrypto module partially implementing the Web Crypto API specification in k6.
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.
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#760Cookies 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#800There 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 the defacto way for developers to measure their frontend performance using the core metrics:
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.
setup and handleSummary.109), used on a go panic.browser.close method is called more than once.browserType.Connect API, users can now connect to an existing browser instance and execute concurrent tests, which was not possible previously.POST and PUT methods for the tracing.instrumentHTTP. Thanks, @marcin-maciej-seweryn!filepath.Join on windows with go1.20, which could cause issues for the k6 archive and k6 cloud commands.check that could return incorrect values for some cases with many preallocated VUs.xk6-websockets updated to v0.2.0 which fixes a lock up of the whole k6.response object's function from jSON to json.page.close so that it closes the current page and not the whole browser context.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:
eventloop.WaitOnRegistered to execute all scheduled callbacks.isNullish to be a part of js/common.sirupsen/logrus usage.lib.TestPreInitState in js/common.InitEnvironment.goja's generator support.browserContext.SetExtraHTTPHeaders to work with errors and ErrFatal.Browser.Launch now transitions to Browser.Connect when a CDP URL is provided in an environment variable.