k6 v0.43.0 is here! :tada:

Notable changes in this release include:
- [xk6-browser](https://github.com/grafana/xk6-browser) is now bundled in k6 as an experimental module, and usable without a separate binary or compilation step!
- Native support for JavaScript's `async`/`await`.
- A new experimental module for distributed tracing.
- Large refactoring of core components to simplify the code base, improve maintainability, and increase test coverage.
- Bug fixes, UX improvements, and maintenance.

Keep reading for the details.

## Breaking changes

- [#2807](https://github.com/grafana/k6/pull/2807) Use non-zero exit codes for tests aborted by Ctrl+C or the REST API.

  Aborting a test run with Ctrl+C will now exit with code `105`, and stopping via the REST API will exit with code `103`.


## New Features

### xk6-browser is now a built-in module [#2884](https://github.com/grafana/k6/pull/2884)

This release includes [xk6-browser](https://github.com/grafana/xk6-browser) as an experimental module. This means you can now also use the main k6 binary for browser automation and end-to-end testing, without needing to build a custom binary with [xk6](https://github.com/grafana/xk6).

All xk6-browser scripts that work with v0.8.0 will continue to work with the built-in module in k6 v0.43.0. To use them, change the import path from `k6/x/browser` to `k6/experimental/browser`, and set the environment variable `K6_BROWSER_ENABLED` to `true`. The requirement to specify the environment variable is temporary and may be removed in a future k6 release. It was added to minimize the risks with k6 unexpectedly launching a browser (or another process) from k6 scripts. It's also a mechanism we use in the k6 Cloud, where browser tests are currently disabled.

For details, review the [script example](https://github.com/grafana/k6/blob/v0.43.0/samples/experimental/browser.js), or the updated [browser module documentation](https://k6.io/docs/javascript-api/k6-browser/).

The module is currently under the `experimental` namespace, which means we reserve the decision to introduce breaking changes in the future. However, our mid-term goal is to drop the `experimental` label and make browser support a stable part of the k6 feature set, eventually enabling it in k6 Cloud as well.


### Native support for JavaScript's `async`/`await` [#2830](https://github.com/grafana/k6/pull/2830)

In [v0.35.0](https://github.com/grafana/k6/releases/tag/v0.35.0) we added support for asynchronous functionality in k6 scripts with the addition of `Promise`.

While useful, the experience wasn't very friendly. Scripts had to use the `.then()` API to chain Promises, instead of the `await` syntax available in most other JavaScript runtimes, and the `async` keyword wasn't supported. [Some workarounds were possible](https://github.com/grafana/k6/issues/779#issuecomment-964027280), but it required a separate build pipeline to transpile the syntax into the older ES5.1+ standard supported by k6.

That is, until now! :tada: With invaluable help from @dop251, who maintains [goja](https://github.com/dop251/goja), the JS VM k6 uses, v0.43.0 brings native `async`/`await` to your k6 scripts. This functionality works just as you'd expect in other JS runtimes, and makes working with async APIs much more convenient. For details, review the following [`http.asyncRequest()` example](#httpasyncrequest-2877).

One caveat to note: async functions can't be passed to `group()` or `check()`. These functions are incompatible with asynchronous behavior, so you will get an error if trying to do so.


### Experimental JavaScript module for distributed tracing [#2853](https://github.com/grafana/k6/pull/2853) [#2854](https://github.com/grafana/k6/pull/2854) [#2855](https://github.com/grafana/k6/pull/2855)

This release brings a new experimental JavaScript module that adds [distributed tracing](https://en.wikipedia.org/wiki/Tracing_(software)) support to k6. With one call in `init` context, you can instrument your test script's HTTP requests. If the system you're testing is instrumented in the same way, this module brings visibility to SUT behavior for the lifetime of each request.

An example:

```javascript
import tracing from 'k6/experimental/tracing';
import http from 'k6/http';

tracing.instrumentHTTP({
  propagator: 'w3c',
});

export default () => {
  http.get('https://httpbin.test.k6.io/get', {
    headers: {
      'X-Example-Header': 'instrumented/get',
    },
  });
};
```

For details and examples, refer to the [tracing module documentation](https://https://k6.io/docs/javascript-api/k6-experimental/tracing/).


### `http.asyncRequest` [#2877](https://github.com/grafana/k6/pull/2877)

The `k6/http` module has a new `asyncRequest` function that takes the same arguments as [`http.request()`](https://k6.io/docs/javascript-api/k6-http/request/), but returns a `Promise` that, when used with `await`, will be resolved with a `Response` object. This gives you more control over script execution, as potentially the most time-consuming calls—making HTTP requests—will no longer block the thread of execution.

An example issuing a POST request:

```javascript
import http from 'k6/http';

export default async function () {
  const resPromise = http.asyncRequest(
    'POST', 'https://httpbin.test.k6.io/post', { name: 'Bert' });
  // Do something else here, make other requests, etc.
  // Then when you're ready to use the response:
  const resp = await resPromise;
  console.log(resp.json().form.name); // Bert
}
```

This is one of the first steps towards migrating our APIs to be asynchronous, and similar changes can be expected in the future.

You can read more about `asyncRequest` in the [documentation](https://k6.io/docs/javascript-api/k6-http/asyncrequest/).


### Enhancements and UX improvements

- [#2754](https://github.com/grafana/k6/pull/2754), [#2805](https://github.com/grafana/k6/pull/2805) The output of the `k6 version` command has been enhanced to also show the version of all extensions built into the k6 binary produced by [xk6](https://github.com/grafana/xk6). Thanks, @HarrisChu!
- [#2800](https://github.com/grafana/k6/pull/2800) Improved handling of the Ctrl+C signal to gracefully abort the test during VU initialization.
- [#2803](https://github.com/grafana/k6/pull/2803) Ensure the REST API server is shut down after the test ends.
- [#2867](https://github.com/grafana/k6/pull/2867) Added the ability to display test run details and logs from k6 Cloud.
- [#2890](https://github.com/grafana/k6/pull/2890) Added a method for JavaScript modules to lookup environment variables without directly accessing the `os` package.
- [#2910](https://github.com/grafana/k6/pull/2910) Added a bit more context when parsing the script options, so that it is more obvious what fails.


## Bug fixes

- [#2829](https://github.com/grafana/k6/pull/2829) The `csv` output now correctly shows `vu` and `iter` system tags. This fixes a regression introduced in v0.40.0. Thanks, @leonyork!
- [#2851](https://github.com/grafana/k6/pull/2851) Calling `k6/execution.test.abort()` within a `group()` now correctly exits the k6 process with code `108`. Thanks for reporting this, @pomeh!
- [#2896](https://github.com/grafana/k6/pull/2896) Fixed a panic in `k6/ws` when using `Socket.setInterval()` with values between 0 and 1.
- [#2903](https://github.com/grafana/k6/pull/2903) Fixed a [regression](https://github.com/grafana/k6/issues/2902) introduced in v0.42.0 where k6 will load the wrong module if the same import specifier has already been loaded, but they are pointing to different absolute paths, based on the files they are imported from.
- [#2907](https://github.com/grafana/k6/pull/2907) Fixed the exit code and `run_status` value when the `cloud` output aborts a test.


## Maintenance and internal improvements

- [#2809](https://github.com/grafana/k6/pull/2809), [#2810](https://github.com/grafana/k6/pull/2810), [#2812](https://github.com/grafana/k6/pull/2812), [#2813](https://github.com/grafana/k6/pull/2813), [#2815](https://github.com/grafana/k6/pull/2815), [#2885](https://github.com/grafana/k6/pull/2885), [#2893](https://github.com/grafana/k6/pull/2893) A core component of test execution, the `Engine`, was removed, and the behavior heavily refactored. This change simplifies the code base and unblocks further improvements.
- [#2821](https://github.com/grafana/k6/pull/2821), [#2864](https://github.com/grafana/k6/pull/2864) Our high-level integration test suite was refactored and expanded, increasing the coverage of behavior that closely replicates real-world usage.
- [#2803](https://github.com/grafana/k6/pull/2803) Enabled checking for goroutine leaks.
- [#2883](https://github.com/grafana/k6/pull/2883) The goja runtime has been updated.
- [#2845](https://github.com/grafana/k6/pull/2845) Lint fixes in the `k6/http` module.
- [#2831](https://github.com/grafana/k6/pull/2831) Compatibility with TC39 error messages was improved.
- [#2846](https://github.com/grafana/k6/pull/2846) The initialization of `js.Bundle` was simplified.
- [#2861](https://github.com/grafana/k6/pull/2861), [#2870](https://github.com/grafana/k6/pull/2870) Some deprecated features and dependencies in our CI pipeline were removed.
- [#2882](https://github.com/grafana/k6/pull/2882) Our Dockerfile was improved with some linter suggestions. Thanks, @kempsterc!

**Full Changelog**: https://github.com/grafana/k6/compare/v0.42.0...v0.43.0
