Skip to content

Commit a9f9e3b

Browse files
ankur22inancgumusAgnesTouletcodebienjoanlopez
authored
Release v1.4.0 (#5363)
* Add v1.4.0 release notes * Add inanc's and external contributor changes * thank elmiringos * clarify 5322 slightly * Add Agnes' changes * OpenTelemetry graduation * Additional breaking change for OTel output * Add Joan's changes * Add auto extension resolution changes * Add ankur22's changes * Remove template bits from release note * Add dependency PR changes * Add #5159 to release note * Add #5216 to the release note * Add external contribution for #5216 * Add winGet support to release note * Add google/uuid update to release note * Add more renovate changes to release note * Add more dep updates to release note * Add missing comma * Other changes by me (@mstoykov) * fix doc links * Remove duplicate issues * Add remaining issues to release notes * Apply suggestions from code review Co-authored-by: Inanc Gumus <inanc.gumus@grafana.com> * fix 5307 code block * Update release notes/v1.4.0.md Co-authored-by: Inanc Gumus <inanc.gumus@grafana.com> * Update release notes/v1.4.0.md Co-authored-by: Inanc Gumus <inanc.gumus@grafana.com> * docs: document k6/x/dns official support * docs: add xk6-dns extension link to release notes * Remove roadmap from release notes --------- Co-authored-by: İnanç Gümüş <inanc.gumus@grafana.com> Co-authored-by: AgnesToulet <35176601+AgnesToulet@users.noreply.github.com> Co-authored-by: codebien <2103732+codebien@users.noreply.github.com> Co-authored-by: Joan López de la Franca Beltran <joanjan14@gmail.com> Co-authored-by: Mihail Stoykov <M.Stoikov@gmail.com> Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com> Co-authored-by: oleiade <theo@crevon.me>
1 parent 3f6d5be commit a9f9e3b

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed

release notes/v1.4.0.md

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
k6 `v1.4.0` is here 🎉! This release includes:
2+
3+
- OpenTelemetry output graduated from experimental to stable status.
4+
- Changes in the Browser module:
5+
- `page.waitForRequest` for waiting on specific HTTP requests.
6+
- `QueryAll` methods now return elements in DOM order.
7+
- `locator.evaluate` and `locator.evaluateHandle` for executing JavaScript code in the page context with access to the matching element.
8+
- `page.unroute(url)` and `page.unrouteAll` for removing routes registered with `page.route`.
9+
10+
## Breaking changes
11+
12+
As per our [stability guarantees](https://grafana.com/docs/k6/latest/reference/versioning-and-stability-guarantees/), breaking changes across minor releases are allowed only for experimental features.
13+
14+
### Breaking changes for experimental modules
15+
16+
- [#5164](https://github.com/grafana/k6/pull/5164) OpenTelemetry output now exports rate metrics as a single counter with `zero`/`nonzero` labels instead of separate metrics.
17+
- [#5333](https://github.com/grafana/k6/pull/5333) OpenTelemetry output configuration: `K6_OTEL_EXPORTER_TYPE` is deprecated in favor of `K6_OTEL_EXPORTER_PROTOCOL` to align with OpenTelemetry standards.
18+
19+
### Breaking changes for undefined behaviours
20+
- [#5320](https://github.com/grafana/k6/pull/5320), [#5239](https://github.com/grafana/k6/pull/5239), [#5342](https://github.com/grafana/k6/pull/5342) Automatic extension resolution now only inspects ES module `import` statements and no longer supports CommonJS `require()` calls. CommonJS `require()` calls are dynamic, and it is not possible to know for certain if they will be called, or if they will be called with static strings - the only way they were even previously loaded. This functionality was a quirk of the previous implementation and had numerous problems. Additionally, `use k6` directives are now only recognized when they appear at the beginning of files (after optional shebang and whitespace/comments). This was the original intention, but due to implementation bugs, it did not accurately reflect what was happening.
21+
22+
## New features
23+
24+
### OpenTelemetry output graduation [#5334](https://github.com/grafana/k6/pull/5334)
25+
26+
The OpenTelemetry output has graduated from experimental status and is now available as a stable output using the name `opentelemetry`. This change makes OpenTelemetry the recommended vendor-agnostic solution for exporting k6 telemetry data.
27+
28+
You can now use the stable output name in your k6 commands:
29+
30+
```bash
31+
# Previous experimental usage (still supported for backward compatibility)
32+
k6 run --out experimental-opentelemetry script.js
33+
34+
# New stable usage
35+
k6 run --out opentelemetry script.js
36+
```
37+
38+
The `experimental-opentelemetry` name will continue to work for backward compatibility for now but it's deprecated and we might remove it in future versions. We recommend migrating to use the new `opentelemetry` name.
39+
40+
### `page.waitForRequest` [#5330](https://github.com/grafana/k6/pull/5330)
41+
42+
The browser module now supports [`page.waitForRequest()`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/waitforrequest/), which allows you to wait for HTTP requests that match specific URL patterns during browser automation. This method is particularly valuable for testing scenarios where you need to ensure specific network requests are initiated before proceeding with test actions.
43+
44+
The method supports multiple URL pattern matching strategies:
45+
46+
```javascript
47+
// Wait for exact URL match
48+
const requestPromise = page.waitForRequest('https://api.example.com/data');
49+
await page.click('button[data-testid="load-data"]');
50+
const request = await requestPromise;
51+
52+
// Wait for regex pattern match
53+
await page.waitForRequest(/\/api\/.*\.json$/);
54+
55+
// Use with Promise.all for coordinated actions
56+
await Promise.all([
57+
page.waitForRequest('https://api.example.com/user-data'),
58+
page.click('button[data-testid="load-user-data"]')
59+
]);
60+
```
61+
62+
This complements the existing [`page.waitForResponse()`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/waitforresponse/) method by focusing on HTTP requests rather than responses, providing more granular control over network-dependent test scenarios.
63+
64+
### `page.unroute(url)` and `page.unrouteAll()` [#5223](https://github.com/grafana/k6/pull/5223)
65+
66+
The browser module now supports [`page.unroute(url)`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/unroute/) and [`page.unrouteAll()`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/page/unrouteall/), allowing you to remove routes previously registered with `page.route`.
67+
68+
Example usage:
69+
```javascript
70+
await page.route(/.*\/api\/pizza/, function (route) {
71+
console.log('Modifying request to /api/pizza');
72+
route.continue({
73+
postData: JSON.stringify({
74+
customName: 'My Pizza',
75+
}),
76+
});
77+
});
78+
...
79+
80+
await page.unroute(/.*\/api\/pizza/); // The URL needs to be exactly the same as the one used in the call to the `route` function
81+
```
82+
83+
```javascript
84+
await page.route(/.*\/api\/pizza/, function (route) {
85+
console.log('Modifying request to /api/pizza');
86+
route.continue({
87+
postData: JSON.stringify({
88+
customName: 'My Pizza',
89+
}),
90+
});
91+
});
92+
...
93+
94+
await page.unrouteAll();
95+
```
96+
97+
### `locator.evaluate` and `locator.evaluateHandle` [#5306](https://github.com/grafana/k6/pull/5306)
98+
99+
The browser module now supports [`locator.evaluate`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/locator/evaluate/) and [`locator.evaluateHandle`](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/locator/evaluatehandle/), allowing you to execute JavaScript code in the page context with access to the matching element. The only difference between `evaluate` and `evaluateHandle` is that `evaluateHandle` returns a [JSHandle](https://grafana.com/docs/k6/latest/javascript-api/k6-browser/jshandle/).
100+
101+
Example usage:
102+
```javascript
103+
await check(page, {
104+
'calling evaluate': async p => {
105+
const n = await p.locator('#pizza-name').evaluate(pizzaName => pizzaName.textContent);
106+
return n == 'Our recommendation:';
107+
}
108+
});
109+
110+
await check(page, {
111+
'calling evaluate with arguments': async p => {
112+
const n = await p.locator('#pizza-name').evaluate((pizzaName, extra) => pizzaName.textContent + extra, ' Super pizza!');
113+
return n == 'Our recommendation: Super pizza!';
114+
}
115+
});
116+
```
117+
118+
```javascript
119+
const jsHandle = await page.locator('#pizza-name').evaluateHandle((pizzaName) => pizzaName);
120+
121+
const obj = await jsHandle.evaluateHandle((handle) => {
122+
return { innerText: handle.innerText };
123+
});
124+
console.log(await obj.jsonValue()); // {"innerText":"Our recommendation:"}
125+
```
126+
127+
### New officially supported [k6 DNS extension](https://github.com/grafana/xk6-dns)
128+
129+
The [`xk6-dns` extension](https://grafana.com/docs/k6/latest/javascript-api/k6-x-dns) is now officially supported in k6 OSS and k6 Cloud. You can import `k6/x/dns` directly in your scripts thanks to [automatic extension resolution](https://grafana.com/docs/grafana-cloud/testing/k6/author-run/use-k6-extensions/), with no custom build required.
130+
131+
Use it to perform DNS resolution testing as part of your tests: resolve names via custom or system DNS, measure resolution latency and errors, validate records before HTTP steps, compare resolvers, and even load test DNS servers in end‑to‑end scenarios.
132+
133+
For example:
134+
135+
```javascript
136+
import dns from 'k6/x/dns';
137+
138+
export default function () {
139+
const answer = dns.resolve('grafana.com', { recordType: 'A' });
140+
console.log(answer.records.map(({ address }) => address).join(', '));
141+
}
142+
```
143+
144+
The extension currently supports A and AAAA record lookups. If you would like to see additional record types supported, please consider [contributing to the extension](https://github.com/grafana/xk6-dns).
145+
146+
147+
### Automatic extension resolution improvements [#5320](https://github.com/grafana/k6/pull/5320), [#5239](https://github.com/grafana/k6/pull/5239), [#5342](https://github.com/grafana/k6/pull/5342), [#5332](https://github.com/grafana/k6/pull/5332), [#5240](https://github.com/grafana/k6/pull/5240)
148+
149+
Automatic extension resolution has been completely reimplemented to use k6's internal module loader instead of the external `k6deps`/esbuild pipeline. This change brings significant improvements in reliability and maintainability.
150+
151+
As part of the rewrite, a few issues and unintended _features_ were found, namely:
152+
1. Trying to follow `require` calls, which, due to their dynamic nature, don't work particularly stably. That is, depending on where and how the `require` call was used, k6 might decide whether it is needed or not. And it definitely doesn't work when using actual string variables. Support for CommonJS is primarily for backward compatibility, so after an internal discussion, we opted not to support it at all. We could bring this back until v2, if there is enough interest. However, in the long term, it is intended that this not be part of k6.
153+
2. "use k6 with ..." directives were parsed from the whole file instead of just the beginning, which leads to numerous problems, and was not the intended case. As such, they are now only parsed at the beginning of files (not just the main one) with potential empty lines and comments preceding them.
154+
155+
**Example:**
156+
157+
```javascript
158+
// main.js
159+
"use k6 with k6/x/faker"
160+
import { faker } from 'k6/x/faker';
161+
import { helper } from './utils.js';
162+
163+
export default function() {
164+
console.log(faker.name());
165+
helper();
166+
}
167+
```
168+
Or, an example using the directive with CommonJS
169+
```javascript
170+
// utils.js
171+
"use k6 with k6/x/redis"
172+
const redis = require('k6/x/redis');
173+
174+
exports.helper = function() {
175+
// Use redis extension
176+
}
177+
```
178+
179+
In this example, k6 will detect both `k6/x/faker` and `k6/x/redis` extensions from the `use k6` directives in both files and provision a binary that includes both extensions if needed.
180+
181+
Other fixes this brings are:
182+
1. Fixes for path related issues (irregardless of usage of the feature) on windows, especially between drives. It is possible there were problems on other OSes that were just not reported. [#5176](https://github.com/grafana/k6/issues/5176)
183+
2. Syntax errors were not reported as such, as the underlying `esbuild` parsing will fail, but won't be handled well. [#5127](https://github.com/grafana/k6/issues/5127), [#5104](https://github.com/grafana/k6/issues/5104)
184+
185+
3. Propagating exit codes from a sub-process running the new k6. This lets you use the result of the exit code.
186+
187+
## UX improvements and enhancements
188+
189+
- [#5307](https://github.com/grafana/k6/pull/5307) `QueryAll` methods now return elements in DOM order. Thank you, @shota3506, for the contribution.
190+
- [#5159](https://github.com/grafana/k6/pull/5159) Simplifies warning message for legacy config files.
191+
- [#5343](https://github.com/grafana/k6/pull/5343) Explictly marks the option's default values.
192+
193+
## Bug fixes
194+
195+
- [#5242](https://github.com/grafana/k6/pull/5242) Fixes cleanup errors on Windows for browser tests.
196+
- [#5246](https://github.com/grafana/k6/pull/5246) Fixes the support for TypeScript source code from stdin.
197+
- [#5322](https://github.com/grafana/k6/pull/5322) Fixes `browser.newPageInContext` bug where pages created in a non-existing browser context.
198+
199+
## Maintenance and internal improvements
200+
201+
- [#5238](https://github.com/grafana/k6/pull/5238) Browser: Fix early context cancellation in tests
202+
- [#5347](https://github.com/grafana/k6/pull/5347), [#5349](https://github.com/grafana/k6/pull/5349) Browser: Move `k6ext.Promise` to the mapping layer.
203+
- [#5340](https://github.com/grafana/k6/pull/5340) Browser: Simplify page event iteration by using an iterator.
204+
- [#5315](https://github.com/grafana/k6/pull/5315), [#5311](https://github.com/grafana/k6/pull/5311) Browser: Revamped page event listening internals for addition of new features and better maintainability.
205+
- [#5339](https://github.com/grafana/k6/pull/5339) Browser: Remove unused `VU` fields.
206+
- [#5314](https://github.com/grafana/k6/pull/5314) Browser: Refactor pattern matcher.
207+
- [#5222](https://github.com/grafana/k6/pull/5222) Browser: Fix linter errors and warnings.
208+
- [#5207](https://github.com/grafana/k6/pull/5207) Browser: Refactor and improve selector parsing. Thank you, @elmiringos for the contribution.
209+
- [#5313](https://github.com/grafana/k6/pull/5313), [#5321](https://github.com/grafana/k6/pull/5321) Update to k6provider v0.2.0 and update code to use the new API.
210+
- [#4682](https://github.com/grafana/k6/pull/4682) Update go-httpbin dependency to v2 and update tests to accommodate breaking changes.
211+
- [#5309](https://github.com/grafana/k6/pull/5309) Update cdproto dependency and fix syntax changes in browser module.
212+
- [#5209](https://github.com/grafana/k6/pull/5209) Update golangci-lint to v2.5.0 and fix related linting issues.
213+
- [#5308](https://github.com/grafana/k6/pull/5308) Format Go Doc comments. Thank you, @shota3506 for the contribution.
214+
- [#5184](https://github.com/grafana/k6/pull/5184) Migrates Prometheus Remote-Write output configuration parsing to `envconfig`.
215+
- [#5304](https://github.com/grafana/k6/pull/5304) Bumps the minimum required Go version to 1.24.
216+
- [#5214](https://github.com/grafana/k6/pull/5214) Update release issue template after 1.3.0
217+
- [#5303](https://github.com/grafana/k6/pull/5303) Fixes code scanning alert no. 102: Incorrect conversion between integer types.
218+
- [#5302](https://github.com/grafana/k6/pull/5302), [#5244](https://github.com/grafana/k6/pull/5244) Refactors Sobek out of business logic and into mapping layer for the browser module.
219+
- [#5247](https://github.com/grafana/k6/pull/5247) Refactors indirection out of locator.go.
220+
- [#4234](https://github.com/grafana/k6/pull/5234), [#5301](https://github.com/grafana/k6/pull/5301), [#5300](https://github.com/grafana/k6/pull/5300), [#5208](https://github.com/grafana/k6/pull/5208) Updates renovate config.
221+
- [#5355](https://github.com/grafana/k6/pull/5355), [#5354](https://github.com/grafana/k6/pull/5354), [#5353](https://github.com/grafana/k6/pull/5353), [#5352](https://github.com/grafana/k6/pull/5352), [#5351](https://github.com/grafana/k6/pull/5351), [#5324](https://github.com/grafana/k6/pull/5324), [#5293](https://github.com/grafana/k6/pull/5293), [#5292](https://github.com/grafana/k6/pull/5292), [#5291](https://github.com/grafana/k6/pull/5291), [#5290](https://github.com/grafana/k6/pull/5290), [#5288](https://github.com/grafana/k6/pull/5288), [#5287](https://github.com/grafana/k6/pull/5287), [#5286](https://github.com/grafana/k6/pull/5286), [#5284](https://github.com/grafana/k6/pull/5284), [#5283](https://github.com/grafana/k6/pull/5283), [#5282](https://github.com/grafana/k6/pull/5282), [#5268](https://github.com/grafana/k6/pull/5268), [#5267](https://github.com/grafana/k6/pull/5267), [#5266](https://github.com/grafana/k6/pull/5266), [#5265](https://github.com/grafana/k6/pull/5265), [#5258](https://github.com/grafana/k6/pull/5258), [#5257](https://github.com/grafana/k6/pull/5257), [#5256](https://github.com/grafana/k6/pull/5256), [#5253](https://github.com/grafana/k6/pull/5253), [#5252](https://github.com/grafana/k6/pull/5252), [#5251](https://github.com/grafana/k6/pull/5251), Updates dependencies.
222+
- [#5216](https://github.com/grafana/k6/pull/5216) Refactors `TestPageOnResponse` to fail fast on errors. Thank you, @rMaxiQp for the contribution.
223+
- [#5203](https://github.com/grafana/k6/pull/5203), [#5201](https://github.com/grafana/k6/pull/5201) Adds WinGet support to the project.
224+
- [#5220](https://github.com/grafana/k6/pull/5220) Switches from gouuid to google/uuid. Thank you, @mikelolasagasti for the contribution.
225+
- [#5344](https://github.com/grafana/k6/pull/5344), [#5345](https://github.com/grafana/k6/pull/5345) Uses .env context for ghcr login when publishing docker images.
226+
- [#5331](https://github.com/grafana/k6/pull/5331) Reports `require` calls during the initial loading of modules, instead for each call in all execution of all VUs.
227+
- [#5218](https://github.com/grafana/k6/pull/5218) Adds user AgnesToulet to the auto assign issue workflow.

0 commit comments

Comments
 (0)