fix(deps): update module go.k6.io/k6 to v0.55.0 #30
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
v0.52.0
->v0.55.0
Release Notes
grafana/k6 (go.k6.io/k6)
v0.55.0
Compare Source
k6
v0.55.0
is here 🎉! This release includes:k6/experimental/tracing
module has been removed.await
support.k6/experimental/webcrypto
.Breaking changes
k6/experimental/tracing
module removed#3855
The experimental
k6/experimental/tracing
module has been removed, in favor of a replacement jslib polyfill, please consult our guide on how to migrate,#3855
.StatsD output removed
#3849
The StatsD output was deprecated in k6 v0.47.0 and is now removed. You could still output results to StatsD using the community xk6 extension LeonAdato/xk6-output-statsd. Thanks, @LeonAdato for taking over the extension!
open
will have a breaking change in the future.Currently,
open
opens relative files based on an unusual root, similar to howrequire
behaved before it was updated for ESM compatibility. To make k6 more consistent,open
and other functions like it will start handling relative paths in the same way as imports andrequire
.For a more in-depth explanation, please refer to the related issue.
With this version, k6 will start emitting warnings when it detects that in the future, this will break. We recommend using
import.meta.resolve()
as a way to make your scripts future proof.http.file#data
now truly has the same type as the provided data#4009
Previously
http.file#data
was always a slice of byte ([]byte
) - which was very likely a bug and a leftover from years past.The original aim (also documented) was to have the same type as the data provided when creating the
http.file
object, and it is now effectively the case.New features
Top-level await support
4007
After the initial native support for ECMAScript modules, k6 can now load those modules asynchronously which also allows
await
to be used in the top-level of a module. That is you can writeawait someFunc()
directly in the top most level of a module instead of having to make an async function that you call that can than useawait
.Until now, you had to wrap your code in an async function to use
await
in the top-level of a module. For example, the following code:Can now be written as:
This should make using the increasing number of async APIs in k6 easier in the init context.
This is not allowed in case of using the CommonJS modules, only ECMAScript modules, as CommonJS modules are synchronous by definition.
Complete[^1] RSA support for
k6/experimental/webcrypto
#4025
This update includes support for the RSA family of algorithms, including
RSA-OAEP
,RSA-PSS
andRSASSA-PKCS1-v1_5
. You can use these algorithms with thecrypto.subtle
API in the same way as the other algorithms, precisely forgenerateKey
,importKey
,exportKey
,encrypt
,decrypt
,sign
, andverify
operations.By implementing RSA support, we make our WebCrypto API implementation more complete and useful for a broader range of use cases.
[^1]: Since under the hood we do fully rely on the Golang's SDK, our implementation doesn't support zero salt lengths for the
RSA-PSS
sign
/verify
operations.Example usage
Expand to see an example of generation RSA-PSS key pair.
page.on('metric)
to group urls browser#371, browser#1487Modern websites are complex and make a high number of requests to function as intended by their developers. These requests no longer serve only content for display to the end user but also retrieve insights, analytics, advertisements, and for cache-busting purposes. Such requests are usually generated dynamically and may contain frequently changing IDs, posing challenges when correlating and analyzing your k6 test results.
When load testing a website using the k6 browser module, these dynamic requests can result in a high number of similar-looking requests, making it difficult to correlate them and extract valuable insights. This can also lead to test errors, such as a "too-many-metrics" error, due to high cardinality from metrics tagged with similar but dynamically changing URLs.
This issue also affects synthetic tests. While you may not encounter the "too-many-metrics" error, you may end up with a large amount of uncorrelated metric data that cannot be tracked effectively over time.
To address this in the browser module, we have implemented
page.on('metric')
, which allows you to define URL patterns using regex for matching. When a match is found, the URL and name tags for the metric are replaced with the new name.Example usage
Expand to see an example of working with `page.on('metric')`.
ControlOrMeta
support in the keyboard browser#1457This approach enables tests to be written for all platforms, accommodating either
Control
orMeta
for keyboard actions. For example,Control+click
on Windows andMeta+click
on Mac to open a link in a new window.Example usage
Expand to see an example usage of `ControlOrMeta`
UX improvements and enhancements
waitForSelector
error message to better reflect why a selector doesn't resolve to an element.experimental-prometheus-rw
output. This allows users to authenticate with AWS services that require SigV4 signing. Thanks, @obanby for the contribution!OTEL_SERVICE_NAME
environment variable for theexperimental-opentelemetry
output. This aligns better with standard OTEL practices. Thanks, @TimotejKovacka for the contribution!page.waitForTimeout
with tracing which will allow it to be displayed in the timeline.Bug fixes
page.on
.locator.waitFor
so it waits between navigations and doesn't throw an error.await
statement.Maintenance and internal improvements
check
helper.page.on
event code to streamline the addition and running of additional events.downloadsPath
option to specify the download directory. The browser module doesn't yet respect this option, but it will in the next release.check
polyfill, for the async checks.v0.54.0
Compare Source
k6
v0.54.0
is here 🎉! This release includes:k6 cloud
commands for local execution and uploading script filesBreaking changes
math/big.Int
type tobigint
type in k6.lib.Min
andlib.Max
from k6's Go API, which could affect custom extensions that rely on these functions.k6/experimental/timers
- they are now available globally and no import is needed.k6/experimental/websockets
, which makes thebinaryType
default value equal to"blob"
. With this change,k6/experimental/websockets
is now compliant with the specification.New features
Branding changes and logo
#3946
,#3953
,#3969
As part of joining Grafana Labs in 2021, k6 was renamed to Grafana k6. The original k6 logo and branding was purple, which didn't fit very well next to the Grafana Labs orange logo and all its other products.
In this release, we have a new logo in a new color, and the terminal banner has been redesigned to match the current branding more closely.
New experimental CSV module for efficient CSV data handling
#3743
We’ve added a new experimental CSV module to k6 for more efficient and convenient CSV parsing and streaming, addressing the limitations of preexisting JavaScript-based solutions like papaparse.
What is it?
The CSV module offers two key features:
csv.parse()
: This function parses a CSV file into a SharedArray at once using Go-based processing for faster parsing and lower memory usage compared to JavaScript alternatives.csv.Parser
: This class provides a streaming parser to read CSV files line-by-line, minimizing memory consumption and offering more control over parsing through a stream-like API. This is ideal for scenarios where memory optimization or fine-grained control of the parsing process is crucial.Benefits for users
csv.parse
bypasses most of the JavaScript runtime, offering significant speed improvements for large files.fs.open
function.csv.parse()
or memory-efficient streaming withcsv.Parser
.Tradeoffs
csv.Parse
: Parses the entire file in the initialization phase of the test, which can increase startup time and memory usage for large files. Best suited for scenarios where performance is prioritized over memory consumption.csv.Parser
: Reads the file line-by-line, making it more memory-efficient but potentially slower due to reading overhead for each line. Ideal for scenarios where memory usage is a concern or where fine-grained control over parsing is needed.Example usage
Expand to see an example of Parsing a full CSV file into a SharedArray.
Expand to see an example of streaming a CSV file line-by-line.
New
k6 cloud run --local-execution
flag for local execution of cloud tests#3904
, and #3931This release introduces the
--local-execution
flag for the k6 cloud run command, allowing you to run test executions locally while sending metrics to Grafana Cloud k6.By default, using the
--local-execution
flag uploads the test archive to Grafana Cloud k6. If you want to disable this upload, use the--no-archive-upload
flag.The
--local-execution
flag currently functions similarly to thek6 run -o cloud
command, which is now considered deprecated (though it is not planned to be removed). Future updates will enhance--local-execution
with additional capabilities that thek6 run -o cloud
command does not offer.New
k6 cloud upload
command for uploading test files to the cloud#3906
We continue to refine and improve the cloud service to improve how we handle uploading test files, so we've added a new
k6 cloud upload
command that replaces thek6 cloud --upload-only
flag, which is now considered deprecated.gRPC module updates driven by contributors
New
discardResponseMessage
option#3877 and #3820 add a new option for the gRPC module
discardResponseMessage
, which allows users to discard the messages received from the server.This reduces the amount of memory required and the amount of garbage collection, which reduces the load on the testing machine and can help produce more reliable test results.
Thank you, @lzakharov!
New argument
meta
for gRPC's stream callbacks#3801 adds a new argument
meta
to gRPC's stream callback, which handles the timestamp of the original event (for example, when a message has been received).Thank you, @cchamplin!
Allow missing file descriptors for gRPC reflection
#3871 allows missing file descriptors for gRPC reflection.
Thank you, @Lordnibbler!
Sobek updates brings support of new ECMAScript features into k6
#3899
,#3925
,#3913
With this release, we've updated Sobek (the
ECMAScript
implementation in Go) which contains the new ECMAScript features that are now available in k6.This includes support for numeric literal separators:
Support for
BigInt
, the values which are too large to be represented by the number primitive:Note: Before k6 version v0.54, Golang's type
math/big.Int
mapped to another type, so this might be a breaking change for some extensions or users.RegExp dotAll support, where you can match newline characters with
.
:Support for ES2023 Array methods:
with
,toSpliced
,toReversed
andtoSorted
.Thank you @shiroyk for adding both the new array methods and BitInt 🙇.
New
setChecked
method for the browser modulebrowser#1403
Previously, users could check or uncheck checkbox and radio button elements using the
check
anduncheck
methods. Now, we've added asetChecked
method that allows users to set a checkbox or radio button to either the checked or unchecked state with a single method and a boolean argument.Page, Frame, ElementHandle, and Locator now support the new
setChecked
method.Async
check
function utilityk6-utils#13
Writing concise code can be difficult when using the k6
check
function with async code since it doesn't support async APIs. A solution that we have suggested so far is to declare a temporary variable, wait for the value that is to be checked, and then check the result later. However, this approach can clutter the code with single-use declarations and unnecessary variable names, for example:To address this limitation, we've added a version of the
check
function to jslib.k6.io that makes working withasync
/await
simpler. Thecheck
function is a drop-in replacement for the built-in check, with added support for async code. AnyPromise
s will be awaited, and the result is reported once the operation has been completed:Check out the
check
utility function's documentation for more information on how to use it.k6/experimnetal/websockets
updates towards WebSockets API compatibilitySupport ArrayBufferViews in
send
fork6/experimental/websockets
#3944As part of making
k6/experimental/websockets
compliant with the WebSocket API, it now supports Uint8Array and other ArrayBufferViews directly as arguments tosend
, instead of having to specifically provide theirbuffer
.This should make the module more compliant with libraries that use the WebSocket API.
Thanks to @pixeldrew for reporting this. 🙇
readyState
actually being a number #3972Due to goja/Sobek internal workings,
readyState
wasn't exactly a number in JavaScript code. This had some abnormal behavior, which limited interoperability with libraries.This has been fixed, and
readyState
is a regular number from the JavaScript perspective.Thanks to @dougw-bc for reporting this. 🙇
Rework of how usage is being collected internally and additional counters
#3917
and#3951
As part of working on k6 over the years, we have often wondered if users use certain features or if they see a strange corner case behavior.
We have usually made guesses or tried to extrapolate from experience on issues we see. Unfortunately, this isn't always easy or possible, and it's definitely very skewed. As such, we usually also add warning messages to things we intend to break to inform people and ask them to report problems. But we usually see very little activity, especially before we make changes.
This also only works for things we want to remove, and it doesn't help us know if people use new functionality at all or if there are patterns we don't expect.
While k6 has been collecting usage for a while, they're surface-level things, such as how many VUs were run, the k6 version, or which internal modules were loaded. The system for this was also very rigid, requiring a lot of work to add simple things, such as if someone used the
require
function.This process has been reworked to make things easier, and a few new usage reports have been added:
require
. Now that we have ESM native support, usingrequire
and CommonJS adds complexity. It's interesting to us whether removing this in the future - likely years, given its support in other runtimes, is feasible.global
. This will help us decide if we can drop compatibility-mode differences or even the whole concept.UX improvements and enhancements
SetupTimeout
option validation. Thank you, @tsukasaI!k6 cloud login
, so now you get immediate feedback right after logging in.✓
and✗
forRate
metrics, and instead uses the form:{x} out of {y}
.Bug fixes
options
isnil
(e.g. exported from a module where it isn't really exported).cloud
command not being display in thek6
command's help text.page.reload
API so handlesnull
responses without exceptions.click
action.browser.close
to abort the cdp close request when the browser process has already exited.Maintenance and internal improvements
go.mod
to the go1.21, introduces toolchain.ExitCode
description typo. Thank you, @eltociear!fatcontext
andcononicalheader
as linters.NetTrail
internal type to simplify internal implementation on emitting iteration and data transmission metric.testutils.MakeMemMapFs
test helper facilitating simulating a file system in tests.TestStreamLogsToLogger
log sending delay to improve the reliability of tests.Roadmap
In version 0.52.0, the browser module transitioned from experimental to stable. The new module is more stable and has a full Async API. To ensure your scripts continue working, you must migrate to the new
k6/browser
module and discontinue using the previousk6/experimental/browser
module. Please see the migration guide for more details.v0.53.0
Compare Source
k6
v0.53.0
is here 🎉! This release includes:k6 cloud
Breaking changes
Require is now specification compliant and always resolves based on the file it is written in #3534
The
require
function in k6 used to resolve identifiers based on the current "root of execution" (more on that later). In a lot of cases, that aligns with the file therequire
is written in or a file in the same folder, which leads to the same result. In a small subset of cases, this isn't the case.In every other implementation, and more or less by the CommonJS specification,
require
should always be relative to the file it is written in.This also aligns with how ESM and dynamic
import
also work. In order to align with themrequire
now uses the same underlying implementation.There was a warning message for the last 2 releases trying to tease out cases where that would be problematic.
"root of execution" explanation
This is very much an implementation detail that has leaked and likely a not intended one.
Whenever a file is
require
-ed it becomes the "root of execution", and bothrequire
andopen
become relative to it. Once therequire
finishes, the previous "root of execution" gets restored. Outside of theinit
context execution, the main file is the "root of execution".Example:
Have 3 files:
main.js
/A/a.js:
/A/b.js
In this example when
require
is called in/A/a.js
themain.js
is once again the "root of execution". If you call the function in/A/a.js
just after defining it though, it will work as expected.You can use the newly added
import.meta.resolve()
function if you want to create a path that is relevant to the currently calling module. That will let you call it outside of a helper class and provide the path to it. Refer to docs for more details.ECMAScript Modules (ESM) Native Support related breaking changes
As part of the ESM native support implementation, two common broken patterns in the ecosystem became apparent.
One is arguably a developer experience improvement, and the other is a consequence of the previous implementation.
Mixing CommonJS and ESM
Previously, k6 used a transpiler (Babel) internally to transpile ESM syntax to CommonJS. That led to all code always being CommonJS, and if you had CommonJS next to it, Babel would not complain.
As k6 (or the underlying JS VM implementation) did not understand ESM in itself and that CommonJS is a 100% during execution feature, this was not easy to detect or prevent.
We added a warning in v0.52.0 to give users time for migration.
To fix this - all you need is to stick to either CommonJS or ESM within each file.
Code examples and proposed changes
In the example above both ESM and CommonJS are used in the same file.
You can either replace:
With the ESM syntax:
Or replace:
With CommonJS:
Imported identifier that can't be resolved are now errors
Previous to this, if you were using the ESM syntax and imported the
foo
identifier, but the exporting file didn't export it, there wouldn't be an error.bar.js:
main.js
The example would not error out, but when it is accessed, there would be an exception as
foo
would beundefined
.With native ESM support, that is an error as defined by the specification and will occur sooner.
This arguably improves UX/DX, but we have reports that some users have imports like this but do not use them. So, they wouldn't be getting exceptions, but they would now get errors.
The solution, in this case, is to stop importing the not exported identifiers.
No more "magic" URL resolution
For a long time, k6 has supported special magic URLs that aren't really that.
Those were URLs without a scheme that:
github.com
, and if pasted to a browser won't open to a file. Their appeal was that you can more easily write them by hand if you know the path within a GitHub repo.cdnjs.com
, and if pasted to a browser will open a web page with all the versions of the library. The appeal here is that you will get the latest version.Both of them had problems though.
The GitHub ones seemed to have never been used by users, likely because you need to guess what the path should look like, and you can always just go get a real URL to the raw file.
While the cdnjs ones have some more usage, they are both a lot more complicated to support, as they require multiple requests to figure out what needs to be loaded. They also change over time. In addition the only known use at the moment is based on a very old example from an issue and it is even pointing to concrete, old version, of a library.
Given that this can be done with a normal URL, we have decided to drop support for this and have warned users for the last couple of versions.
Deprecated
k6/experimental/tracing
in favor of a JavaScript implementationk6/experimental/tracing
is arguably not very well named, and there is a good chance we would like to use the name for actual trace and span support within k6 in the future.On top of that it can now be fully supported in js code, which is why http-instrumentation-tempo
was created.
The JavaScript implementation is a drop-in replacement, so all you need to do is replace
k6/experimental/tracing
withhttps://jslib.k6.io/http-instrumentation-tempo/1.0.0/index.js
.The module is planned to be removed in v0.55.0, planned for November 11th, 2024.
Experimental websockets now require
binaryType
to be set to receive binary messagesAs part of the stabilization of the
k6/experimental/websockets
we need to move the default value ofbinaryType
toblob
. It was previouslyarraybuffer
and since the last version there was a warning that it needs to be set in order for binary messages to be received.That warning is now an error.
In the future we will move the default value to
blob
and remove the error.New features
The new features include:
k6 cloud
Native ESM support #3456
With this feature k6 is now ES6+ compliant natively. Which means (asterisk free) support for the spread operator with object, private class fields and optional chaining
But also faster startup times, more consistent errors and easier addition of features as we now only need to add them to Sobek instead of also them being supported in the internal Babel.
History of compatibility mode and ECMAScript specification compliance
Some history: More than 6 years ago k6 started using core-js and babel to get ES6+ features. core-js is a implementation of a lot of the types and their features such as
String.prototype.matchAll
among other things, and Babel gets one piece of code that uses some syntax and returns a piece of code doing the same thing (mostly) but with different syntax. Usually with the idea of supporting newer syntax but returning code that can run on runtimes which only support old syntax.This is great, but it means that:
Both of those aren't that big problems usually, but the runtime k6 uses is fairly fast, but isn't V8. What it lacks in speed it gets back in being easy to interact with from Go, the language k6 is written in.
But it means that now on each start it needs to do a bunch of work that adds up.
So long time ago for people who would want to not have to do this we added compatibility-mode=base. This allowed you to potentially not use this features and get a big speedup. Or use them outside of k6 and likely still get significant speed up if you cut down on it.
At the same time the author and maintainer of the JS runtime we used (goja) did implement a big portion of what we were missing from core-js and also Babel. After some experiments to cut down the core-js we import we ended up contributing back the remaining parts and dropping the whole library. Which lead to 5 times reduction of memory per VU for simple scripts. And even for fairly complicated ones.
With this in mind we did try to cut down Babel as well and contribute back the simpler things it was used for. This over the years lead to small pieces of what Babel did being moved to goja and then disabled in Babel. Some of those were just easy wins, some of those were things that had very bad pathological cases where using a particular syntax made transpilation times explode.
In all of that work there always were small (or not so small) breaking changes due to many factors - sometimes our new implementation was slightly wrong and we needed to fix, sometimes more than what was in the standard was enabled in core-js or Babel, sometimes the standard changed on those. And sometimes the implementation in Babel or core-js wasn't as full and didn't account for all corner cases.
ECMAScript Modules(ESM) is the last such feature that Babel was used for. It also happens to be likely the one most people used, due to the fact that it is the standard way to reuse code and import libraries.
While the work on this feature started over 2 years ago, it both depended on other features that weren't there yet, but also interacts with more or less every other feature that is part of the ECMAScript standard.
Along the way there were many internal refactors as well as additional tests to make certain we can be as backwards compatible as possible. But there also ended up being things that just weren't going to be compatible, like the listed breaking changes.
After ESM now being natively supported, compatibility-mode
base
vsextended
has only 1 feature difference - aliasingglobal
toglobalThis
to make it a bit more compatible with (old) Node.js. There is ongoing discussion if that as well should be removed.For the purposes of having less intrusive changes and shipping this earlier a few things have not been implemented in k6. That includes top-level-await and dynamic import support. Both of them are likely to land in the next version.
import.meta.resolve()
gets an URL from a relative path the same wayimport
orrequire
does #3873As part of the move to ESM a lot of cases where k6 currently do not resolve the same relative path to the same file were found. Some of those were fixed - as those in
require
, but others haven't.It also became apparent some users do use the relativity of
require
, but alsoopen
. As we move to make this consistent among uses, we decided to let users have a better transition path forward.Using
import.meta.resolve
will give you just a new URL that can be used in all functions and it will give you the same result.import.meta.resolve
uses the same algorithm and relativity as ESM import syntax. Refer to docs for more details.Blob support in the experimental websockets module grafana/xk6-websockets#74
In order to support the default
WebSocket.binaryType
type as per spec ("blob"
), we have added support for theBlob
interface as part of the features included in thexk6-websockets
module.So, from now on it can be used with
import { Blob } from "k6/experimental/websockets";
. In the future, apart from graduating this module to stable, we might also want to expose theBlob
interface globally (no imports will be required). But for now, please remind that its support is still experimental, as the entire module is. Refer to the docs for more details.Experimental OpenTelemetry Output #3834
This release introduces a new experimental output for OpenTelemetry. This allows users to send k6 metrics to any OpenTelemetry-compatible backends. More details and usage examples can be found in the documentation.
To output metrics to OpenTelemetry, use the
experimental-opentelemetry
output option:If you have any feedback or issues, please let us know directly in the extension repository.
Consolidating cloud features under
k6 cloud
#3813This release introduces the first iteration of the revamped cloud-related commands under the
k6 cloud
command, featuring two new subcommands:k6 cloud login
: replacesk6 login cloud
for authenticating with the cloud service. It supports token-based authentication only. The previous authentication method using email and password will still be available through the legacyk6 login cloud
command, which is now deprecated and will be removed in a future release (no removal date set yet).k6 cloud run
: is the new official way to run k6 on the cloud service, serving as an alternative to the existingk6 cloud
command. Thek6 cloud
command will remain available for a few more versions but will eventually function only as a wrapper for all cloud-related commands, without any direct functionality.UX improvements and enhancements
Bug fixes
Maintenance and internal improvements
BrowserContextOptions
into mapping layer.k6/experimental/timers
deprecation warning updates.Roadmap
Future breaking changes
Experimental browser module removal
In the previous release, the browser module graduated from experimental to stable. The
k6/experimental/browser
module will be removed inv0.54.0
. To keep your scripts working you need to migrate to thek6/browser
module.Experimental timers module removal
The experimental timers module has been deprecated for a few versions. It both has a stable import path
k6/timers
, but also all of it's current exports are available globally.In the next version
v0.54.0
the experimental timers module will be removed.Experimental tracing module removal
The experimental tracing module is deprecated in this version. In two versions(
v0.55.0
) the experimental module will be removed.To keep your scripts working you need to migrate to http-instrumentation-tempo jslib.
StatsD removal
In this release, we also fixed the version where we will remove the StatsD output. The StatsD output is going to be removed in the
v0.55.0
release. If you are using the StatsD output, please consider migrating to the extension LeonAdato/xk6-output-statsd.Potentially dropping
global
fromextended
compatibility-modeCurrently
global
is aliased toglobalThis
whenextended
compatibility-mode is used. This is currently the only difference with thebase
compatibility-mode.Given that this seems to have very low usage it might be dropped in the future. See the issue for more info or if you want to comment on this.
Configuration
📅 Schedule: Branch creation - "after 10pm every weekday,before 5am every weekday,every weekend" in timezone Asia/Tokyo, Automerge - At any time (no schedule defined).
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.