-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Release Notes for v0.54.0 #3949
base: master
Are you sure you want to change the base?
Changes from 28 commits
99bb3aa
8b29604
10b57a8
ec5a854
a85e5a0
b42d1b1
a52892e
b3bce17
5c3bbaf
cd79b78
8da0ce8
befe03c
dfe6c0f
a42b2ff
f13b796
901251f
4fd717d
dea59ed
4b63d34
4b33ce6
be907c9
469ecb4
d30a86d
802430d
e575ea4
6a9971b
cac0382
af29a66
ad5a90a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,304 @@ | ||||||||||||||||||||||||||||||||||||
k6 `v0.54.0` is here 🎉! This release includes: | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
- A new experimental CSV module | ||||||||||||||||||||||||||||||||||||
- new ECMAScript features | ||||||||||||||||||||||||||||||||||||
- Updated logo and branding | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
## Breaking changes | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
- [#3913](https://github.com/grafana/k6/pull/3913) changes mapping of the Golang's `math/big.Int` type to `bigint` type in k6. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
- [#3922](https://github.com/grafana/k6/pull/3922) removes `lib.Min` and `lib.Max` from k6's Go API, which could affect custom extensions that rely on these functions. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do these two items require any docs updates? 🤔 |
||||||||||||||||||||||||||||||||||||
- [#3838](https://github.com/grafana/k6/pull/3838) remove `k6/experimental/timers` - they are now available globally and no import is needed. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
- [#3944](https://github.com/grafana/k6/pull/3844) updates to `k6/experimental/websockets` made the default to binaryType to be `"blob"` as per the specification. Previously it was not set by default and required to be set and before that it was `"arraybuffer"`. With this change `k6/experimental/websockets` is now compliant with the specification. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I reworded it a bit to make it easier to read, but I'm wondering if we could make it more concise and just say: "- #3944 updates to What do you think? |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### (_optional h3_) `<big_breaking_change>` `#pr` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
## New features | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### Branding changes and logo [`#3946`](https://github.com/grafana/k6/pull/3946), [`#3953`](https://github.com/grafana/k6/pull/3953) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
As part of Grafana Labs, k6 got renamed to Grafana k6, instead of k6.io. We also had a purple icon making a bit jarring next to all the other orange-y ones. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
As such in this release we also got a new logo and the terminal banner has been redesigned to more closely match the current branding. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
![image](https://github.com/grafana/k6/blob/31e3db711850fdd270e56e53feb3a2e4209e542a/assets/logo.svg) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### New `k6 cloud run --local-execution` flag for local execution of cloud tests [`#3904`](https://github.com/grafana/k6/pull/3904), and [#3931](https://github.com/grafana/k6/pull/3931) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
This release introduces the --local-execution flag for the k6 cloud run command, allowing you to run test executions locally while sending the metrics to Grafana Cloud k6. | ||||||||||||||||||||||||||||||||||||
```bash | ||||||||||||||||||||||||||||||||||||
Comment on lines
+28
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
k6 cloud run --local-execution | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Do we want to add a script path here? |
||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
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 the `k6 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 the `k6 run -o cloud` command does not offer. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### New experimental CSV module for efficient CSV data handling [`#3743`](https://github.com/grafana/k6/pull/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](https://www.papaparse.com/). | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#### What is it? | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
The csv module offers two key features: | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
* `csv.parse()` **Function**: Parses an entire CSV file at once into a [SharedArray](https://grafana.com/docs/k6/latest/javascript-api/k6-data/sharedarray/), using Go-based processing to using Go-based processing for faster parsing and lower memory usage compared to JavaScript alternatives. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
* `csv.Parser` **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. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#### Benefits for Users | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
* **Faster Parsing**: `csv.parse` bypasses most of the JavaScript runtime, offering significant speed improvements for large files. | ||||||||||||||||||||||||||||||||||||
* **Lower Memory Usage**: both solution support shared memory across virtual users (VUs) with the `fs.open` function. | ||||||||||||||||||||||||||||||||||||
* **Flexibility**: choose between full-file parsing with csv.parse() or memory-efficient streaming with csv.Parser. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+51
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#### 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 | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
<details> | ||||||||||||||||||||||||||||||||||||
<summary> Expand to see an example of Parsing a full CSV file into a SharedArray.</summary> | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
import { open } from 'k6/experimental/fs' | ||||||||||||||||||||||||||||||||||||
import csv from 'k6/experimental/csv' | ||||||||||||||||||||||||||||||||||||
import { scenario } from 'k6/execution' | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export const options = { | ||||||||||||||||||||||||||||||||||||
iterations: 10, | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
let file; | ||||||||||||||||||||||||||||||||||||
let csvRecords; | ||||||||||||||||||||||||||||||||||||
(async function () { | ||||||||||||||||||||||||||||||||||||
file = await open('data.csv'); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// The `csv.parse` function consumes the entire file at once, and returns | ||||||||||||||||||||||||||||||||||||
// the parsed records as a SharedArray object. | ||||||||||||||||||||||||||||||||||||
csvRecords = await csv.parse(file, {delimiter: ','}) | ||||||||||||||||||||||||||||||||||||
})(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export default async function() { | ||||||||||||||||||||||||||||||||||||
// The csvRecords a SharedArray. Each element is a record from the CSV file, represented as an array | ||||||||||||||||||||||||||||||||||||
// where each element is a field from the CSV record. | ||||||||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||||||||
// Thus, `csvRecords[scenario.iterationInTest]` will give us the record for the current iteration. | ||||||||||||||||||||||||||||||||||||
console.log(csvRecords[scenario.iterationInTest]) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
</details> | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
<details> | ||||||||||||||||||||||||||||||||||||
<summary> Expand to see an example of streaming a CSV file line-by-line.</summary> | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
import { open } from 'k6/experimental/fs' | ||||||||||||||||||||||||||||||||||||
import csv from 'k6/experimental/csv' | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export const options = { | ||||||||||||||||||||||||||||||||||||
iterations: 10, | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
let file; | ||||||||||||||||||||||||||||||||||||
let parser; | ||||||||||||||||||||||||||||||||||||
(async function () { | ||||||||||||||||||||||||||||||||||||
file = await open('data.csv'); | ||||||||||||||||||||||||||||||||||||
parser = new csv.Parser(file); | ||||||||||||||||||||||||||||||||||||
})(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export default async function() { | ||||||||||||||||||||||||||||||||||||
// The parser `next` method attempts to read the next row from the CSV file. | ||||||||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||||||||
// It returns an iterator-like object with a `done` property that indicates whether | ||||||||||||||||||||||||||||||||||||
// there are more rows to read, and a `value` property that contains the row fields | ||||||||||||||||||||||||||||||||||||
// as an array. | ||||||||||||||||||||||||||||||||||||
const {done, value} = await parser.next(); | ||||||||||||||||||||||||||||||||||||
if (done) { | ||||||||||||||||||||||||||||||||||||
throw new Error("No more rows to read"); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// We expect the `value` property to be an array of strings, where each string is a field | ||||||||||||||||||||||||||||||||||||
// from the CSV record. | ||||||||||||||||||||||||||||||||||||
console.log(done, value); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
</details> | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### New `k6 cloud upload` command for uploading test files to the cloud [`#3906`](https://github.com/grafana/k6/pull/3906) | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we still need a docs PR for this update. |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Although we continue to refine and improve the cloud service to handle better the uploading of test files, | ||||||||||||||||||||||||||||||||||||
as well as the overall user experience, we've added a new `k6 cloud upload` command that replaces the | ||||||||||||||||||||||||||||||||||||
`k6 cloud --upload-only` flag used so far, which is now considered deprecated. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+134
to
+136
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### gRPC module updates driven by contributors | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#### New `discardResponseMessage` option | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
[#3877](https://github.com/grafana/k6/pull/3877) and [#3820](https://github.com/grafana/k6/pull/3820) add a new option for gRPC module `discardResponseMessage` which allows users to discard the messages received from the server. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
const resp = client.invoke('main.RouteGuide/GetFeature', req, {discardResponseMessage: true}); | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
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. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Thank you, @lzakharov! | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#### New argument `meta` for gRPC's stream callbacks | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this might need a docs update as well. |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
[#3801](https://github.com/grafana/k6/pull/3801) adds a new argument `meta` to gRPC's stream callback, which handles the timestamp of the original event (e.g. when message has been received). | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
We try to avoid using e.g. and i.e. based on our writing style guide. |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
let stream = new grpc.Stream(client, "main.FeatureExplorer/ListFeatures") | ||||||||||||||||||||||||||||||||||||
stream.on('data', function (data, meta) { | ||||||||||||||||||||||||||||||||||||
// will print the timestamp when message has been received | ||||||||||||||||||||||||||||||||||||
call(meta.ts); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Thank you, @cchamplin! | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#### Allow missing file descriptors for gRPC reflection | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
[#3871](https://github.com/grafana/k6/pull/3871) allows missing file descriptors for gRPC reflection. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Thank you, @Lordnibbler! | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### Sobek updates brings support of new ECMAScript features into k6 [`#3899`](https://github.com/grafana/k6/pull/3899), [`#3925`](https://github.com/grafana/k6/pull/3925), [`#3913`](https://github.com/grafana/k6/pull/3913) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
With this release, we've updated [Sobek](https://github.com/grafana/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, like: | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
const billion = 1_000_000_000 | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Support for `BigInt`, the values which are too large to be represented by the number primitive. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
const huge = BigInt(9007199254740991); | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Note: that prior k6 version v0.54, Golang's type `math/big.Int` mapped to another type, so it might be a breaking change for some extensions or users. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Regexp dotall support - letting you match newline characters with `.`. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+188
to
+190
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
const str1 = "bar\nexample foo example"; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
const regex1 = /bar.example/s; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
console.log(regex1.dotAll); // true | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Support for ES2023 Array methods: [`with`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/with), [`toSpliced`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSpliced), [`toReversed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed) and [`toSorted`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted). | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Thank you @shiroyk for adding both the new array methods and BitInt :bow:. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### New `setChecked` method for the browser module [`browser#1403`](https://github.com/grafana/xk6-browser/pull/1403) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Previously, users could check or uncheck checkbox and radio button elements using the [`check`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/check/) and [`uncheck`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/uncheck/) methods. Now, we've added a `setChecked` 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. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
await page.setChecked('#checkbox', true); // check the checkbox | ||||||||||||||||||||||||||||||||||||
await page.setChecked('#checkbox', false); // uncheck the checkbox | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
[Page](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/setchecked/), [Frame](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/frame/setchecked/), [ElementHandle](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/elementhandle//setchecked/), and [Locator](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/locator/setchecked/) now support the new `setChecked` method. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### Async `check` function utility [`k6-utils#13`](https://github.com/grafana/k6-jslib-utils/pull/13) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Writing concise code can be difficult when using [the k6 `check` function](https://grafana.com/docs/k6/latest/javascript-api/k6/check/) 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, e.g.: | ||||||||||||||||||||||||||||||||||||
inancgumus marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
const checked = await p.locator('.checked').isChecked(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
check(checked, { | ||||||||||||||||||||||||||||||||||||
'checked': c => c, | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
To address this limitation, we've added a version of the `check` function to [jslib.k6.io](https://jslib.k6.io/) that makes working with `async`/`await` more ergonomic. The `check` function is a drop-in replacement for the built-in check, with added support for async code. Any `Promise`s will be awaited, and the result is reported once the operation has been completed: | ||||||||||||||||||||||||||||||||||||
inancgumus marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
```javascript | ||||||||||||||||||||||||||||||||||||
// Import the new check function from jslib.k6.io/k6-utils | ||||||||||||||||||||||||||||||||||||
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js'; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// ... | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Use the new check function with async code | ||||||||||||||||||||||||||||||||||||
check(page, { | ||||||||||||||||||||||||||||||||||||
'checked': async p => p.locator('.checked').isChecked(), | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Check out [the `check` utility function's documentation](https://grafana.com/docs/k6/latest/javascript-api/jslib/utils/check/) for more information on how to use it. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### Support ArrayBufferViews in send for `k6/experimental/websockets` [#3944](https://github.com/grafana/k6/pull/3844) | ||||||||||||||||||||||||||||||||||||
heitortsergent marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
As part of making `k6/experimental/websockets` complaint with the [WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) it now support Uint8Array and other ArrayBufferViews directly as arguments to `send`, instead of having to specifically provide their `buffer`. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
This should make it more compliant with libraries that use WebSocket API. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Thanks to @pixeldrew for [reporting](https://github.com/grafana/xk6-websockets/issues/75) this :bow: | ||||||||||||||||||||||||||||||||||||
Comment on lines
+243
to
+249
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
### Rework of how usage is being collected internally and additional counters [`#3917`](https://github.com/grafana/k6/pull/3917) and [`#3951`](https://github.com/grafana/k6/pull/3951) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
As part of working on k6 over the years we have many times wondered if given features is used or if this strange corner case behavior is being used. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
We usually made guesses or tried to extrapolate from experience on issues we see or maybe even cloud customers. This unfortunately isn't always easy or possible at all and definitely is very skewed. As such we usually also added warning messages to thing we intend on breaking to let people know and ask them to report if they see problems. This usually see very little activity especially before we make the changes. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
This also only works for things we want to remove, but doesn't help us know if people use new functionality at all or if there are patterns that we do not expect. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+254
to
+258
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
While k6 has been collecting usage for a while it is usually very surface level stuff, such as how many VUs were run, k6 version, what *internal* modules were loaded and such. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
And the system for this was very rigid requiring usually a lot of work to add simple stuff, like if someone used the `require` function. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
This has been reworked to make this a lot easier to do and a few new usage reports have been added: | ||||||||||||||||||||||||||||||||||||
- when cloud is used it will also tell us which test run it is. We already have most if not actually more of the information reported through metrics and it being ran in the cloud. But this will also help us filter cloud from not cloud runs easier and also potentially tell cloud users that they are using experimental modules that are to be removed soon. | ||||||||||||||||||||||||||||||||||||
- number of files parsed as well as number of ts files parsed. This will be useful both in us figuring out if people use small projects or bigger ones as well as if ts file support is being used. | ||||||||||||||||||||||||||||||||||||
- usage of `require`. Now that we have ESM native support, using `require` and CommonJS adds complexity. It is interesting to us whether removing this in the future - likely years, given it support in other runtimes, is even feasable. | ||||||||||||||||||||||||||||||||||||
- usage of `global`. This for help us decide if we can [drop compatility-mode](https://github.com/grafana/k6/issues/3864) differences or even the whole concept of them. | ||||||||||||||||||||||||||||||||||||
Comment on lines
+260
to
+268
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
## UX improvements and enhancements | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
- [#3898](https://github.com/grafana/k6/pull/3898) adds `SetupTimeout` option validation. Thank you, @tsukasaI! | ||||||||||||||||||||||||||||||||||||
- [#3930](https://github.com/grafana/k6/pull/3930) adds token validation for `k6 cloud login`, so now you get immediate feedback right after logging in. | ||||||||||||||||||||||||||||||||||||
- [#3876](https://github.com/grafana/k6/pull/3876), [#3923](https://github.com/grafana/k6/pull/3923) adjusts the process' exit code for cloud test runs where thresholds have failed. | ||||||||||||||||||||||||||||||||||||
- [#3765](https://github.com/grafana/k6/pull/3765) stops using the confusing `✓` and `✗` for `Rate` metrics, and instead uses the form: `{x} out of {y}`. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
## Bug fixes | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
- [#3947](https://github.com/grafana/k6/pull/3947) fixes panic when `options` is `nil` (e.g. exported from a module where it isn't really exported). | ||||||||||||||||||||||||||||||||||||
- [browser#1406](https://github.com/grafana/xk6-browser/pull/1406) fixes panic on iframe attach when iframe didn't contain any UI elements. | ||||||||||||||||||||||||||||||||||||
- [browser#1420](https://github.com/grafana/xk6-browser/pull/1420) uses the VU context to control the iterations lifecycle which helps k6 shutdown in a timely manner when a test is aborted. | ||||||||||||||||||||||||||||||||||||
- [browser#1421](https://github.com/grafana/xk6-browser/pull/1421) fixes the navigation span by starting when the page starts to load so that it's a better representation of how long the test was on a page. | ||||||||||||||||||||||||||||||||||||
- [browser#1408](https://github.com/grafana/xk6-browser/pull/1408), [#1422](https://github.com/grafana/xk6-browser/pull/1422) fixes the `page.reload` API so handles `null` responses without exceptions. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
## Maintenance and internal improvements | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
- [#3915](https://github.com/grafana/k6/pull/3915) switches `go.mod` to the go1.21, introduces toolchain. | ||||||||||||||||||||||||||||||||||||
- [#3938](https://github.com/grafana/k6/pull/3938) updates k6's CI workflows to go 1.23. | ||||||||||||||||||||||||||||||||||||
- [#3939](https://github.com/grafana/k6/pull/3939) updates Dockerfile to use go 1.23 and alpine 3.20. | ||||||||||||||||||||||||||||||||||||
- [#3909](https://github.com/grafana/k6/pull/3909) fixes `ExitCode` description typo. Thank you, @eltociear! | ||||||||||||||||||||||||||||||||||||
- [#3926](https://github.com/grafana/k6/pull/3926) documents maintenance of tc39 tests. | ||||||||||||||||||||||||||||||||||||
- [#3881](https://github.com/grafana/k6/pull/3881) adds top-level roadmap link. | ||||||||||||||||||||||||||||||||||||
- [#3945](https://github.com/grafana/k6/pull/3945) updates the endpoint where [usage reports](https://grafana.com/docs/k6/latest/set-up/usage-collection/) are sent to. | ||||||||||||||||||||||||||||||||||||
- [#3903](https://github.com/grafana/k6/pull/3903), [#3912](https://github.com/grafana/k6/pull/3912), [#3928](https://github.com/grafana/k6/pull/3928) update dependencies. | ||||||||||||||||||||||||||||||||||||
- [browser#1419](https://github.com/grafana/xk6-browser/pull/1419), [browser#1423](https://github.com/grafana/xk6-browser/pull/1423) adds a new remote file upload protocol. | ||||||||||||||||||||||||||||||||||||
- [#3900](https://github.com/grafana/k6/pull/3900) and [#3902](https://github.com/grafana/k6/pull/3902) Update golangci-lint to 1.60.1 and add fatcontext and cononicalheader as linters. | ||||||||||||||||||||||||||||||||||||
- [#3908](https://github.com/grafana/k6/pull/3908) drop NetTrail internal type to simplify internal implementation on emitting iteration and data transmission metric. | ||||||||||||||||||||||||||||||||||||
- [#3935](https://github.com/grafana/k6/pull/3935) refactor some js tests to remove repeated setup code. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
## Roadmap | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
In version 0.52.0, the browser module [transitioned](https://github.com/grafana/k6/pull/3793) from the experimental phase to stable. The new module is more stable and has a [full Async API](https://github.com/grafana/xk6-browser/pull/1374). To ensure your scripts continue working, you must migrate to the new `k6/browser` module and discontinue using the previous `k6/experimental/browser` module. Please see [the migration guide](https://grafana.com/docs/k6/latest/using-k6-browser/migrating-to-k6-v0-52/) for more details. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
_Discussion of future plans_ | ||||||||||||||||||||||||||||||||||||
inancgumus marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.