Important: This documentation is about an older version. It's relevant only to the release noted, many of the features and functions have been updated or replaced. Please view the current version.
Migrating to k6 v0.46
This guide outlines the key changes you will need to make when moving your existing k6 browser test scripts to the new k6 browser module (bundled with k6 version 0.46).
Key changes
The updated version introduces notable structural changes in its operation and API, including breaking changes:
- The import path for the browser module has switched from
chromium
tobrowser
. - Simplified resource management. The browser module now handles the startup and shutdown of browser processes automatically. The
chromium.launch()
,chromium.connect()
, andbrowser.close()
methods are no longer necessary and have been removed. - Browser options can now only be set using environment variables.
- Scenario options must now be defined for running browser tests.
- Single browser context per iteration. You can now only run a single BrowserContext at a time in the same iteration.
Note
You no longer need to use theK6_BROWSER_ENABLED
flag when running browser tests with thek6
command.
Before and after comparison
Let’s start with an overview of the main differences between the previous and new versions of the k6 browser API.
import { chromium } from 'k6/experimental/browser';
export default async function () {
const browser = chromium.launch({
headless: false,
timeout: '60s',
});
const page = browser.newPage();
try {
await page.goto('https://test.k6.io/');
page.screenshot({ path: 'screenshot.png' });
} finally {
page.close();
browser.close();
}
}
import { browser } from 'k6/experimental/browser';
export const options = {
scenarios: {
ui: {
executor: 'shared-iterations',
options: {
browser: {
type: 'chromium',
},
},
},
},
};
export default async function () {
const page = browser.newPage();
try {
await page.goto('https://test.k6.io/');
page.screenshot({ path: 'screenshot.png' });
} finally {
page.close();
}
}
Import path
With the browser type (specifically chromium
) now set in scenario options, you should directly import the browser object from the browser module.
import { chromium } from 'k6/experimental/browser';
import { browser } from 'k6/experimental/browser';
Simplified resource management
The browser lifecycle is now automatically managed by the browser module, and so the chromium.launch()
, chromium.connect()
, and browser.close()
methods are no longer necessary and have been removed.
Now, all that is needed is to specify the browser.type
within the scenario options. If the option is set, a browser instance will automatically start at the beginning and close at the end of each test iteration.
Browser options
With the removal of the chromium.launch()
and chromium.connect()
methods, setting browsers options is now done by using environment variables. For more information, refer to Browser Module Options.
Launching a browser
Before:
export default async function () {
const browser = chromium.launch({
headless: false,
timeout: '60s',
});
}
After:
$ K6_BROWSER_HEADLESS=false K6_BROWSER_TIMEOUT='60s' k6 run script.js
# WARNING!
# The grafana/k6:master-with-browser image launches a Chrome browser by setting the
# 'no-sandbox' argument. Only use it with trustworthy websites.
#
# As an alternative, you can use a Docker SECCOMP profile instead, and overwrite the
# Chrome arguments to not use 'no-sandbox' such as:
# docker container run --rm -i -e K6_BROWSER_ARGS='' --security-opt seccomp=$(pwd)/chrome.json grafana/k6:master-with-browser run - <script.js
#
# You can find an example of a hardened SECCOMP profile in:
# https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json.
docker run --rm -i -e K6_BROWSER_HEADLESS=false -e K6_BROWSER_TIMEOUT='60s' grafana/k6:master-with-browser run - <script.js
C:\k6> set "K6_BROWSER_HEADLESS=false" && set "K6_BROWSER_TIMEOUT='60s' " && k6 run script.js
PS C:\k6> $env:K6_BROWSER_HEADLESS="false" ; $env:K6_BROWSER_TIMEOUT='60s' ; k6 run script.js
Connecting to a remote browser
Before:
export default async function () {
const remoteURL = 'REMOTE_URL';
const browser = chromium.connect(remoteURL);
const page = browser.newPage();
}
After:
$ K6_BROWSER_WS_URL='REMOTE_URL' k6 run script.js
# WARNING!
# The grafana/k6:master-with-browser image launches a Chrome browser by setting the
# 'no-sandbox' argument. Only use it with trustworthy websites.
#
# As an alternative, you can use a Docker SECCOMP profile instead, and overwrite the
# Chrome arguments to not use 'no-sandbox' such as:
# docker container run --rm -i -e K6_BROWSER_ARGS='' --security-opt seccomp=$(pwd)/chrome.json grafana/k6:master-with-browser run - <script.js
#
# You can find an example of a hardened SECCOMP profile in:
# https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json.
docker run --rm -i -e K6_BROWSER_WS_URL='REMOTE_URL' grafana/k6:master-with-browser run - <script.js
C:\k6> set "K6_BROWSER_WS_URL='REMOTE_URL'" && set "K6_BROWSER_TIMEOUT='60s' && k6 run script.js
PS C:\k6> $env:K6_BROWSER_WS_URL='REMOTE_URL' ; k6 run script.js
Note
The following browser options are no longer supported:devtools
,env
, andproxy
since they weren’t providing much value.slowMo
has been temporarily removed, and we’re working on reintroducing it.
Scenario options
You must now set the executor and browser type as options in a scenario definition. Specifically, the browser.type
option should be set to chromium
, as Chromium is the only browser supported.
export const options = {
scenarios: {
ui: {
executor: 'shared-iterations',
options: {
browser: {
type: 'chromium',
},
},
},
},
};
Opening and closing a page
You can open a new page by using the imported browser object’s browser.newPage() method. You can still use the Page object as before.
export default async function () {
const browser = chromium.launch();
const page = browser.newPage();
// ...
page.close();
browser.close();
}
export default async function () {
const page = browser.newPage();
// ...
page.close();
}
The browser.close()
method has been removed, so you can remove that from your scripts and use page.close()
once you’re done using the page object.
Note
Closing of the page is critical for the calculation of accurate Web Vital metrics. See the browser metrics for more details.
Browser context limit
The new browser implementation limits the usage to a single active BrowserContext per iteration. This change enhances the prediction of resource requirements for a test run and promotes the use of scenarios to separate independent browser sessions.
- A new BrowserContext can be created either with the browser.newContext() or browser.newPage() methods.
- If a new BrowserContext needs to be created, the existing one must be closed first using the browserContext.close() method.
- Alongside these changes, the
browser.contexts()
method has been altered to browser.context() to retrieve the current BrowserContext.
For instance, the code below will not function as intended, as it attempts to execute two simultaneous BrowserContexts within the same iteration.
export default async function () {
const context1 = browser.newContext();
// Simultaneous browser contexts are not permitted!
const context2 = browser.newContext();
}
On the other hand, the next example will function correctly by closing the initial BrowserContext prior to establishing a new one.
export default async function () {
const context1 = browser.newContext();
context1.close();
// Since the first browser context is closed, a new browser context can be created.
const context2 = browser.newContext();
context2.close();
}
These updates make the usage of the API more straightforward for users, aiding in more consistent and automatic resource management.
For all the details, make sure to review the complete changelog for k6 version 0.46. For more information watch k6 Office Hours #98, where we discuss the latest changes in k6 browser, and, as always, ask in the community forum if you need help!