-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
--------- Co-authored-by: ankur22 <[email protected]> Co-authored-by: oleiade <[email protected]> Co-authored-by: İnanç Gümüş <[email protected]> Co-authored-by: Oleg Bespalov <[email protected]> Co-authored-by: Mihail Stoykov <[email protected]> Co-authored-by: Joan López de la Franca Beltran <[email protected]>
- Loading branch information
1 parent
c9d463a
commit 33d3caa
Showing
1 changed file
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
k6 `v0.51.0` is here 🎉! Some special mentions included in this release: | ||
|
||
- [A new experimental streams module](#introduction-of-k6experimentalstreams-module-3696) | ||
- [New algorithms for WebCrypto module](#new-features-and-updates-of-webcrypto-api-support-3714) | ||
- [Timers are globally available](#timers-globally-available-3589) | ||
|
||
## Breaking changes | ||
|
||
### Transition browser APIs to Async | ||
|
||
In the last release notes [we mentioned](https://github.com/grafana/k6/blob/master/release%20notes/v0.50.0.md#browser-apis-to-async) this breaking change, and we wanted to remind and update you on the plan. In the **next** release (v0.52.0), most of the synchronous browser APIs will be migrated to be asynchronous (promisifying them). We expect this will affect most if not all of our users. | ||
|
||
This breaking change will require you to add `await` in front of most of the browser module APIs. Without this `await` you will witness undocumented and unknown behavior during the runtime. To make the migration simpler we advise that you work with the latest [k6 type definitions](https://grafana.com/docs/k6/latest/set-up/configure-k6-intellisense/). | ||
|
||
You can find a list of all the APIs that we expect to convert to async in a comment in issue [browser#428](https://github.com/grafana/xk6-browser/issues/428#issuecomment-1964020837). | ||
|
||
Awaiting on something that’s not a thenable just returns that value, which means you can add the `await` keyword today on the APIs that will become async to future proof your test scripts. | ||
|
||
Here are the reasons for making this large breaking change: | ||
|
||
1. Most browser APIs use some form of long-running IO operation (networking) to perform the requested action on the web browser against the website under test. We need to avoid blocking JavaScript's runtime event loop for such operations. | ||
2. We're going to add more asynchronous event-based APIs (such as [page.on](https://github.com/grafana/xk6-browser/issues/1227)) that our current synchronous APIs would block. | ||
3. To align with how developers expect to work with JavaScript APIs. | ||
4. To have better compatibility with Playwright. | ||
|
||
As a starting point, we have migrated a single API (the `tap` method), which you can find the details below that will help visualize the upcoming breaking changes. | ||
|
||
### Browser `Tap` is now an async method grafana/xk6-browser#1268 | ||
|
||
This release converts the `Tap` method in the `browser` module into an asynchronous method. This change is necessary to ensure that the method can be used in async contexts and to align with the rest of the browser module's planned asynchronous API. To use the `Tap` method, you must now add the `await` keyword before the method call. | ||
|
||
Affected components: | ||
- [`locator.tap`](https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/browser/locator/tap/) | ||
- [`page.tap`](https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/browser/page/tap/) | ||
- [`frame.tap`](https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/browser/frame/) | ||
- [`elementHandle.tap`](https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/browser/elementhandle/) | ||
|
||
See the following example for how to use the `Tap` method after this change: | ||
|
||
**Before**: | ||
|
||
```javascript | ||
import browser from 'k6/experimental/browser' | ||
|
||
// ... | ||
|
||
export default function () { | ||
// ... | ||
page.tap(selector, { modifiers: ["Alt", "Control", "Meta", "Shift"] }); | ||
// ... | ||
} | ||
``` | ||
|
||
**After**: | ||
|
||
```javascript | ||
import browser from 'k6/experimental/browser' | ||
|
||
// ... | ||
|
||
export default function () { | ||
// ... | ||
await page.tap(selector, { modifiers: ["Alt", "Control", "Meta", "Shift"] }); | ||
// ... | ||
} | ||
``` | ||
|
||
### `k6/experimental/websockets` will not default `binaryType` to `"arraybuffer"' | ||
|
||
As part of the stabilization of the API it needs to become as close to the specification. | ||
|
||
Early in the development the idea of adding `Blob` support as part was deemed feature creep and was dropped in favor of going with only `"arraybuffer"`. But the specification defaults to returning binary responses as `Blob` - which was another thing that was changed. | ||
|
||
While adding `Blob` is still on our radar, moving the default is always going to be a breaking change that we need to do to align with the specification. | ||
|
||
For this release there is now a warning that will be printed if `binaryType` is not set to `"arraybuffer"` *and* a binary response is received. The warning will go away when `binaryType` is set to `"arraybuffer"`. | ||
|
||
In the next release the warning will become an error. | ||
|
||
More info and place for discussion can be found in an [this issue](https://github.com/grafana/xk6-websockets/issues/67). | ||
|
||
### `k6/experimental/grpc` is no longer available [#3530](https://github.com/grafana/k6/pull/3530) | ||
|
||
As the last step of the graduation process for the experimental gRPC module, we completely removed the module. It is now fully integrated into the stable `k6/net/grpc` module. So, if you haven't done this yet, replace your imports from `k6/experimental/grpc` to `k6/net/grpc`. | ||
|
||
### Deprecations | ||
|
||
The following pull requests start the process to introduce breaking changes. They are currently starting to emit warning if their condition is hit, but they will turn to return errors in the future release. | ||
It is recommended to use the suggested alternative, or to fix the script if you see the warning message. | ||
|
||
- [#3681](https://github.com/grafana/k6/pull/3681) Use of not-compliant `require` expressions. | ||
- [#3680](https://github.com/grafana/k6/pull/3680) Modules resolution of modules not previously seen during the initialization phase. | ||
- [#3676](https://github.com/grafana/k6/pull/3676) Working directory is set to the current location when the script is provided using stdin, instead of the root folder. | ||
- [#3530](https://github.com/grafana/k6/pull/3671) Automagically resolve modules from cdnjs and github "URLs". | ||
|
||
## New features | ||
|
||
### Introduction of `k6/experimental/streams` module [#3696](https://github.com/grafana/k6/pull/3696) | ||
|
||
This release of k6 introduces the new `k6/experimental/streams` module, which partially supports the JavaScript | ||
Streams API, focusing initially on the `ReadableStream` construct. | ||
|
||
With the `ReadableStream`, users can define and consume data streams within k6 scripts. This is particularly useful for | ||
efficiently handling large datasets or for processing data sequentially in a controlled flow. | ||
|
||
<details> | ||
<summary> Expand to see an example of stream's usage</summary> | ||
|
||
The following example demonstrates creating and consuming a simple stream that emits numbers until it reaches a predefined limit: | ||
|
||
```javascript | ||
import { ReadableStream } from 'k6/experimental/streams' | ||
|
||
function numbersStream() { | ||
let currentNumber = 0 | ||
|
||
return new ReadableStream({ | ||
start(controller) { | ||
const fn = () => { | ||
if (currentNumber < 5) { | ||
controller.enqueue(++currentNumber) | ||
setTimeout(fn, 1000) | ||
return; | ||
} | ||
|
||
controller.close() | ||
} | ||
setTimeout(fn, 1000) | ||
}, | ||
}) | ||
} | ||
|
||
export default async function () { | ||
const stream = numbersStream() | ||
const reader = stream.getReader() | ||
|
||
while (true) { | ||
const { done, value } = await reader.read() | ||
if (done) break | ||
console.log(`received number ${value} from stream`) | ||
} | ||
|
||
console.log('we are done') | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
For more advanced examples, please head to the MDN Web Docs on the [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API). | ||
|
||
#### Limitations | ||
|
||
Currently, users can define and consume readable streams. However, this release does not include support for byte readers | ||
and controllers, nor does it include support the `tee`, `pipeTo`, and | ||
`pipeThrough` methods of the `ReadableStream` object. | ||
|
||
### New features and updates of WebCrypto API support [#3714](https://github.com/grafana/k6/pull/3714) | ||
|
||
This release brings support for asymmetric cryptography to the `k6/experimental/webcrypto` module. We added support of the elliptic curves algorithms ECDH ([xk6-webcrypto#67](https://github.com/grafana/xk6-webcrypto/pull/67)) and ECDSA ([xk6-webcrypto#69](https://github.com/grafana/xk6-webcrypto/pull/69)) algorithms along with new import/export key formats like `spki` and `pkcs8`. | ||
|
||
One of the newly added operations is `deriveBits`, which allows parties to generate a unique shared secret by using shared public and non-shared private keys. | ||
|
||
<details> | ||
<summary> Expand to see an example of generating a shared secret for Alice and Bob.</summary> | ||
|
||
```javascript | ||
import { crypto } from 'k6/experimental/webcrypto'; | ||
|
||
export default async function () { | ||
// Generate a key pair for Alice | ||
const aliceKeyPair = await crypto.subtle.generateKey( | ||
{ | ||
name: 'ECDH', | ||
namedCurve: 'P-256', | ||
}, | ||
true, | ||
['deriveKey', 'deriveBits'] | ||
); | ||
|
||
// Generate a key pair for Bob | ||
const bobKeyPair = await crypto.subtle.generateKey( | ||
{ | ||
name: 'ECDH', | ||
namedCurve: 'P-256', | ||
}, | ||
true, | ||
['deriveKey', 'deriveBits'] | ||
); | ||
|
||
// Derive shared secret for Alice | ||
const aliceSharedSecret = await deriveSharedSecret(aliceKeyPair.privateKey, bobKeyPair.publicKey); | ||
|
||
// Derive shared secret for Bob | ||
const bobSharedSecret = await deriveSharedSecret(bobKeyPair.privateKey, aliceKeyPair.publicKey); | ||
|
||
// alice shared secret and bob shared secret should be the same | ||
console.log('alice shared secret: ' + printArrayBuffer(aliceSharedSecret)); | ||
console.log('bob shared secret: ' + printArrayBuffer(bobSharedSecret)); | ||
} | ||
|
||
async function deriveSharedSecret(privateKey, publicKey) { | ||
return crypto.subtle.deriveBits( | ||
{ | ||
name: 'ECDH', | ||
public: publicKey, | ||
}, | ||
privateKey, | ||
256 | ||
); | ||
} | ||
|
||
const printArrayBuffer = (buffer) => { | ||
const view = new Uint8Array(buffer); | ||
return Array.from(view); | ||
}; | ||
``` | ||
|
||
</details> | ||
|
||
The `sign` and `verify` operations got support for ECDSA algorithm. The `sign` operation allows you to sign a message with a private key, while the `verify` operation allows you to verify the signature with a public key. | ||
|
||
Other notable updates and fixes: | ||
|
||
- [xk6-webcrypto#68](https://github.com/grafana/xk6-webcrypto/pull/68) fixes a degradation for the sign/verify operations for HMAC algorithm. | ||
- [xk6-webcrypto#75](https://github.com/grafana/xk6-webcrypto/pull/75), [xk6-webcrypto#76](https://github.com/grafana/xk6-webcrypto/pull/76) refactor webcrypto module to be thread-safe. | ||
- [xk6-webcrypto#74](https://github.com/grafana/xk6-webcrypto/pull/74) adds JWK import/export support for ECDH and ECDSA. Refactors JWK import/export to use only go standard library. | ||
|
||
See [webcrypto's module documentation](https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/webcrypto/) for more details. | ||
|
||
### Timers globally available [#3589](https://github.com/grafana/k6/pull/3589) | ||
|
||
`setTimeout`, `setInterval` and related clear functions have been part of the JavaScript ecosystem, probably for as long as it has existed. | ||
|
||
In the previous releases we stabilized and made them available through `k6/timers` module. While the module isn't going anywhere and might get more identifiers, `setTimeout` is usually used without importing it. For this reason it is now globally available along `clearTimeout`, `setInterval` and `clearInterval`. | ||
|
||
No code needs to be changed, but you no longer need to import `k6/timers` to use this functionality. | ||
|
||
## UX improvements and enhancements | ||
|
||
- [#3670](https://github.com/grafana/k6/issues/3670) adds the ability to [enable profiling](https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/#profiling-enabled) via environment variable. Thanks @Bablzz for your contribution! | ||
- [#3655](https://github.com/grafana/k6/pull/3655) clarifies the error message for the validation of scenario's name. | ||
- [#3693](https://github.com/grafana/k6/pull/3693) adds a gRPC client's `asyncInvoke` method to the `k6/net/grpc` module. It's [a non-blocking version](https://grafana.com/docs/k6/latest/javascript-api/k6-net-grpc/client/client-async-invoke/) of the `invoke` method. | ||
- [browser#1259](https://github.com/grafana/xk6-browser/pull/1259), [browser#1260](https://github.com/grafana/xk6-browser/pull/1260) adds errors to the traces that the browser module generates. | ||
|
||
## Bug fixes | ||
|
||
- [#3708](https://github.com/grafana/k6/pull/3708) denies access to `execution.test.options` from Init context. | ||
- [#3672](https://github.com/grafana/k6/pull/3672) picks the correct value when [SystemTags](https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/#system-tags) are set via the `k6_SYSTEM_TAGS` environment variable. | ||
- [#3657](https://github.com/grafana/k6/pull/3657) fixes a panic when `mappings` field is empty in the provided SourceMap. | ||
- [#3717](https://github.com/grafana/k6/pull/3717) returns a correct line number when an inlined SourceMap is used. | ||
- [browser#1261](https://github.com/grafana/xk6-browser/pull/1261) fixes dispose context canceled errors. | ||
- [browser#1254](https://github.com/grafana/xk6-browser/pull/1254) fixes an indefinite wait when testing websites with iframes. | ||
- [browser#1291](https://github.com/grafana/xk6-browser/pull/1291) fixes a panic on dispose of resources during a navigation. | ||
|
||
## Maintenance and internal improvements | ||
|
||
- [#3663](https://github.com/grafana/k6/pull/3663), [#3673](https://github.com/grafana/k6/pull/3673) updates several dependencies. | ||
- [#3674](https://github.com/grafana/k6/pull/3674) updates the Go version, now k6 binary is built and tested using Go 1.22. | ||
- [#3688](https://github.com/grafana/k6/pull/3688) updates the link to installation instructions for `golangci-lint` in the contribution guide. Thanks @yomek33 for your contribution! | ||
- [browser#1262](https://github.com/grafana/xk6-browser/pull/1262) fixes a flaky test. | ||
- [browser#1264](https://github.com/grafana/xk6-browser/pull/1264) removes unimplemented APIs. | ||
|
||
## Future plans | ||
|
||
### Use Blob as default value for WebSocket.binaryType | ||
|
||
As the changes in documentation mention, [`binaryType`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/binaryType) was by default set to `arraybuffer`, now instead it is `""` (empty string). | ||
In a not so remote future, instead, we expect to introduce and use Blob object. | ||
|
||
### WebCrypto graduation | ||
|
||
WebCrypto got more features in the current release, and we expect to continue its expansion in the next iterations. Reaching a wider coverage will push WebCrypto module to being graduated as a stable module. | ||
|
||
### Streams API | ||
|
||
In the not so distant future, we have plans to start using the Streams API in existing modules. Our first iteration being adding a `.readable` property to the already existing [fs.File](https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/fs/file) object. | ||
|
||
### Improve user experience for Cloud related commands | ||
|
||
In the near future, we intend to reiterate on `k6 cloud` and related commands to create a simplified and more ergonomic user experience. | ||
|
||
### Remove experimental timers module | ||
|
||
The `k6/experimental/timers` module is now part of the stable k6 API as `k6/timers` and via the globally available functions. The next release will make the experimental import no longer available. |