<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Examples on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/examples/</link><description>Recent content in Examples on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/k6/v2.3.x/examples/index.xml" rel="self" type="application/rss+xml"/><item><title>Get started with k6</title><link>https://grafana.com/docs/k6/v2.3.x/examples/get-started-with-k6/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/get-started-with-k6/</guid><content><![CDATA[&lt;h1 id=&#34;get-started-with-k6&#34;&gt;Get started with k6&lt;/h1&gt;
&lt;p&gt;This tutorial provides some procedures for common real-life uses of k6.
They assume no prior knowledge of k6 or of JavaScript.&lt;/p&gt;
&lt;p&gt;These tasks are all reproducible, so open up your favorite editor and follow along.
Imagine that you are a developer or tester who is responsible for performance in your development team.&lt;/p&gt;
&lt;h2 id=&#34;context-test-a-new-endpoint&#34;&gt;Context: test a new endpoint&lt;/h2&gt;
&lt;p&gt;Your development team has just developed a new login endpoint.
Before releasing, you must test the endpoint for the following questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does it work?&lt;/li&gt;
&lt;li&gt;Does it perform within the service-level objectives under average load?&lt;/li&gt;
&lt;li&gt;At what load does performance degrade beyond objectives?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After you test the endpoint, your team wants you to compare different components of the user-facing application.&lt;/p&gt;
&lt;p&gt;Finally, after you test the API and web application, break your scripts down into reusable parts.&lt;/p&gt;
&lt;h2 id=&#34;before-you-start&#34;&gt;Before you start&lt;/h2&gt;
&lt;p&gt;We encourage you to open your terminal and actively experiment with these examples.
The tutorial requires the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34; /&gt; 
    &lt;a href=&#34;/docs/k6/v2.3.x/set-up/install-k6/&#34;&gt;k6 installed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34; /&gt; A clean directory to experiment in.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34; /&gt; Something to do during the minute or two when k6 runs the longest example tests&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34; /&gt; Optional: &lt;a href=&#34;https://stedolan.github.io/jq/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt; to filter some results&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tutorials&#34;&gt;Tutorials&lt;/h2&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;In this tutorial&lt;/th&gt;
              &lt;th&gt;Learn how to&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/examples/get-started-with-k6/test-for-functional-behavior/&#34;&gt;Test for functional behavior&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Use k6 to script requests and evaluate that performance is correct&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/examples/get-started-with-k6/test-for-performance/&#34;&gt;Test for performance&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Use k6 to increase load and find faults&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/examples/get-started-with-k6/analyze-results/&#34;&gt;Analyze results&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Filter results and make custom metrics&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/examples/get-started-with-k6/reuse-and-re-run-tests/&#34;&gt;Reuse and re-run&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Modularize and re-run tests&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;]]></content><description>&lt;h1 id="get-started-with-k6">Get started with k6&lt;/h1>
&lt;p>This tutorial provides some procedures for common real-life uses of k6.
They assume no prior knowledge of k6 or of JavaScript.&lt;/p></description></item><item><title>Single request</title><link>https://grafana.com/docs/k6/v2.3.x/examples/single-request/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/single-request/</guid><content><![CDATA[&lt;h1 id=&#34;single-request&#34;&gt;Single request&lt;/h1&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

export const options = {
  iterations: 1,
};

export default function () {
  const response = http.get(&amp;#39;https://quickpizza.grafana.com&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="single-request">Single request&lt;/h1>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import http from &amp;#39;k6/http&amp;#39;;
export const options = {
iterations: 1,
};
export default function () {
const response = http.get(&amp;#39;https://quickpizza.grafana.com&amp;#39;);
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div></description></item><item><title>HTTP Authentication</title><link>https://grafana.com/docs/k6/v2.3.x/examples/http-authentication/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/http-authentication/</guid><content><![CDATA[&lt;h1 id=&#34;http-authentication&#34;&gt;HTTP Authentication&lt;/h1&gt;
&lt;p&gt;Scripting examples on how to use different authentication or authorization methods in your load test.&lt;/p&gt;
&lt;h2 id=&#34;basic-authentication&#34;&gt;Basic authentication&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import encoding from &amp;#39;k6/encoding&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

const username = &amp;#39;user&amp;#39;;
const password = &amp;#39;passwd&amp;#39;;

export default function () {
  const credentials = `${username}:${password}`;

  // Passing username and password as part of the URL will
  // allow us to authenticate using HTTP Basic Auth.
  const url = `https://${credentials}@quickpizza.grafana.com/api/basic-auth/${username}/${password}`;

  let res = http.get(url);

  // Verify response
  check(res, {
    &amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#39;is authenticated&amp;#39;: (r) =&amp;gt; r.json().authenticated === true,
    &amp;#39;is correct user&amp;#39;: (r) =&amp;gt; r.json().user === username,
  });

  // Alternatively you can create the header yourself to authenticate
  // using HTTP Basic Auth
  const encodedCredentials = encoding.b64encode(credentials);
  const options = {
    headers: {
      Authorization: `Basic ${encodedCredentials}`,
    },
  };

  res = http.get(`https://quickpizza.grafana.com/api/basic-auth/${username}/${password}`, options);

  // Verify response (checking the echoed data from the QuickPizza
  // basic auth test API endpoint)
  check(res, {
    &amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#39;is authenticated&amp;#39;: (r) =&amp;gt; r.json().authenticated === true,
    &amp;#39;is correct user&amp;#39;: (r) =&amp;gt; r.json().user === username,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;ntlm-authentication&#34;&gt;NTLM authentication&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

const username = &amp;#39;user&amp;#39;;
const password = &amp;#39;passwd&amp;#39;;

export default function () {
  // Passing username and password as part of URL and then specifying
  // &amp;#34;ntlm&amp;#34; as auth type will do the trick!
  const credentials = `${username}:${password}`;
  const res = http.get(`http://${credentials}@example.com/`, { auth: &amp;#39;ntlm&amp;#39; });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;aws-signature-v4-authentication-with-the-k6-jslib-aws&#34;&gt;AWS Signature v4 authentication with the &lt;a href=&#34;https://github.com/grafana/k6-jslib-aws&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;k6-jslib-aws&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To authenticate requests to AWS APIs using &lt;a href=&#34;https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;AWS Signature Version 4&lt;/a&gt;, k6 offers the &lt;a href=&#34;https://github.com/grafana/k6-jslib-aws&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;k6-jslib-aws&lt;/a&gt; JavaScript library, which provides a dedicated &lt;code&gt;SignatureV4&lt;/code&gt; class. This class can produce authenticated requests to send to AWS APIs using the &lt;code&gt;http&lt;/code&gt; k6 module.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example script to demonstrate how to sign a request to fetch an object from an S3 bucket:&lt;/p&gt;
&lt;!-- md-k6:skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import {
  AWSConfig,
  SignatureV4,
} from &amp;#39;https://jslib.k6.io/aws/0.14.0/signature.js&amp;#39;;

const awsConfig = new AWSConfig({
  region: __ENV.AWS_REGION,
  accessKeyId: __ENV.AWS_ACCESS_KEY_ID,
  secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY,

  /**
   * Optional session token for temporary credentials.
   */
  sessionToken: __ENV.AWS_SESSION_TOKEN,
});

export default function () {
  /**
   * Create a signer instance with the AWS credentials.
   * The signer will be used to sign the request.
   */
  const signer = new SignatureV4({
    service: &amp;#39;s3&amp;#39;,
    region: awsConfig.region,
    credentials: {
      accessKeyId: awsConfig.accessKeyId,
      secretAccessKey: awsConfig.secretAccessKey,
      sessionToken: awsConfig.sessionToken,
    },
  });

  /**
   * Use the signer to prepare a signed request.
   * The signed request can then be used to send the request to the AWS API.
   */
  const signedRequest = signer.sign(
    {
      method: &amp;#39;GET&amp;#39;,
      protocol: &amp;#39;https&amp;#39;,
      hostname: &amp;#39;test-jslib-aws.s3.us-east-1.amazonaws.com&amp;#39;,
      path: &amp;#39;/bonjour.txt&amp;#39;,
      headers: {},
      uriEscapePath: false,
      applyChecksum: false,
    },
    {
      signingDate: new Date(),
      signingService: &amp;#39;s3&amp;#39;,
      signingRegion: &amp;#39;us-east-1&amp;#39;,
    }
  );

  /**
   * The `signedRequest` object contains the signed request URL and headers.
   * We can use them to send the request to the AWS API.
   */
  http.get(signedRequest.url, { headers: signedRequest.headers });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="http-authentication">HTTP Authentication&lt;/h1>
&lt;p>Scripting examples on how to use different authentication or authorization methods in your load test.&lt;/p>
&lt;h2 id="basic-authentication">Basic authentication&lt;/h2>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import encoding from &amp;#39;k6/encoding&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;
const username = &amp;#39;user&amp;#39;;
const password = &amp;#39;passwd&amp;#39;;
export default function () {
const credentials = `${username}:${password}`;
// Passing username and password as part of the URL will
// allow us to authenticate using HTTP Basic Auth.
const url = `https://${credentials}@quickpizza.grafana.com/api/basic-auth/${username}/${password}`;
let res = http.get(url);
// Verify response
check(res, {
&amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
&amp;#39;is authenticated&amp;#39;: (r) =&amp;gt; r.json().authenticated === true,
&amp;#39;is correct user&amp;#39;: (r) =&amp;gt; r.json().user === username,
});
// Alternatively you can create the header yourself to authenticate
// using HTTP Basic Auth
const encodedCredentials = encoding.b64encode(credentials);
const options = {
headers: {
Authorization: `Basic ${encodedCredentials}`,
},
};
res = http.get(`https://quickpizza.grafana.com/api/basic-auth/${username}/${password}`, options);
// Verify response (checking the echoed data from the QuickPizza
// basic auth test API endpoint)
check(res, {
&amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
&amp;#39;is authenticated&amp;#39;: (r) =&amp;gt; r.json().authenticated === true,
&amp;#39;is correct user&amp;#39;: (r) =&amp;gt; r.json().user === username,
});
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;h2 id="ntlm-authentication">NTLM authentication&lt;/h2>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import http from &amp;#39;k6/http&amp;#39;;
const username = &amp;#39;user&amp;#39;;
const password = &amp;#39;passwd&amp;#39;;
export default function () {
// Passing username and password as part of URL and then specifying
// &amp;#34;ntlm&amp;#34; as auth type will do the trick!
const credentials = `${username}:${password}`;
const res = http.get(`http://${credentials}@example.com/`, { auth: &amp;#39;ntlm&amp;#39; });
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;h2 id="aws-signature-v4-authentication-with-the-k6-jslib-aws">AWS Signature v4 authentication with the &lt;a href="https://github.com/grafana/k6-jslib-aws" target="_blank" rel="noopener noreferrer">k6-jslib-aws&lt;/a>&lt;/h2>
&lt;p>To authenticate requests to AWS APIs using &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html" target="_blank" rel="noopener noreferrer">AWS Signature Version 4&lt;/a>, k6 offers the &lt;a href="https://github.com/grafana/k6-jslib-aws" target="_blank" rel="noopener noreferrer">k6-jslib-aws&lt;/a> JavaScript library, which provides a dedicated &lt;code>SignatureV4&lt;/code> class. This class can produce authenticated requests to send to AWS APIs using the &lt;code>http&lt;/code> k6 module.&lt;/p></description></item><item><title>OAuth Authentication</title><link>https://grafana.com/docs/k6/v2.3.x/examples/oauth-authentication/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/oauth-authentication/</guid><content><![CDATA[&lt;h1 id=&#34;oauth-authentication&#34;&gt;OAuth Authentication&lt;/h1&gt;
&lt;p&gt;Scripting examples on how to use OAuth authentication in your load test.&lt;/p&gt;
&lt;h2 id=&#34;oauth-authentication-1&#34;&gt;OAuth authentication&lt;/h2&gt;
&lt;p&gt;The following examples take a set of arguments, shown in the function documentation, and returns the response body as JSON so that you can extract the token from.&lt;/p&gt;
&lt;h3 id=&#34;azure-active-directory&#34;&gt;Azure Active Directory&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

/**
 * Authenticate using OAuth against Azure Active Directory
 * @function
 * @param  {string} tenantId - Directory ID in Azure
 * @param  {string} clientId - Application ID in Azure
 * @param  {string} clientSecret - Can be obtained from https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app#create-a-client-secret
 * @param  {string} scope - Space-separated list of scopes (permissions) that are already given consent to by admin
 * @param  {string} resource - Either a resource ID (as string) or an object containing username and password
 */
export function authenticateUsingAzure(tenantId, clientId, clientSecret, scope, resource) {
  let url;
  const requestBody = {
    client_id: clientId,
    client_secret: clientSecret,
    scope: scope,
  };

  if (typeof resource == &amp;#39;string&amp;#39;) {
    url = `https://login.microsoftonline.com/${tenantId}/oauth2/token`;
    requestBody[&amp;#39;grant_type&amp;#39;] = &amp;#39;client_credentials&amp;#39;;
    requestBody[&amp;#39;resource&amp;#39;] = resource;
  } else if (
    typeof resource == &amp;#39;object&amp;#39; &amp;amp;&amp;amp;
    resource.hasOwnProperty(&amp;#39;username&amp;#39;) &amp;amp;&amp;amp;
    resource.hasOwnProperty(&amp;#39;password&amp;#39;)
  ) {
    url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
    requestBody[&amp;#39;grant_type&amp;#39;] = &amp;#39;password&amp;#39;;
    requestBody[&amp;#39;username&amp;#39;] = resource.username;
    requestBody[&amp;#39;password&amp;#39;] = resource.password;
  } else {
    throw &amp;#39;resource should be either a string or an object containing username and password&amp;#39;;
  }

  const response = http.post(url, requestBody);

  return response.json();
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;azure-b2c&#34;&gt;Azure B2C&lt;/h3&gt;
&lt;p&gt;The following example shows how you can authenticate with Azure B2C using the &lt;a href=&#34;https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-oauth-code#client-credentials-flow&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Client Credentials Flow&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This example is based on a JMeter example found at the &lt;a href=&#34;https://github.com/azure-ad-b2c/load-tests&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;azure-ad-b2c/load-tests&lt;/a&gt; repository.&lt;/p&gt;
&lt;p&gt;To use this script, you need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-tenant&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Set up your own Azure B2C tenant&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Copy the tenant name, it will be used in your test script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Register a web application&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Register a single page application with the redirect URL of: &lt;a href=&#34;https://jwt.ms&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://jwt.ms&lt;/a&gt;. That&amp;rsquo;s needed for the flow to receive a token.&lt;/li&gt;
&lt;li&gt;After the creation, you can get the Application (client) ID, and the Directory (tenant) ID. Copy both of them, they&amp;rsquo;ll be used in your test script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Create a user flow so that you can sign up and create a user&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Create a new user, and copy the username and password. They&amp;rsquo;ll be used in the test script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can find the settings in the B2C settings in the Azure portal if you need to refer to them later on. Make sure to fill out all the variables for the &lt;code&gt;B2CGraphSettings&lt;/code&gt; object, as well as replace &lt;code&gt;USERNAME&lt;/code&gt; and &lt;code&gt;PASSWORD&lt;/code&gt; in &lt;code&gt;export default function&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import crypto from &amp;#39;k6/crypto&amp;#39;;
import { randomString } from &amp;#39;https://jslib.k6.io/k6-utils/1.2.0/index.js&amp;#39;;

const B2CGraphSettings = {
  B2C: {
    client_id: &amp;#39;&amp;#39;, // Application ID in Azure
    user_flow_name: &amp;#39;&amp;#39;,
    tenant_id: &amp;#39;&amp;#39;, // Directory ID in Azure
    tenant_name: &amp;#39;&amp;#39;,
    scope: &amp;#39;openid&amp;#39;,
    redirect_url: &amp;#39;https://jwt.ms&amp;#39;,
  },
};

/**
 * Authenticate using OAuth against Azure B2C
 * @function
 * @param  {string} username - Username of the user to authenticate
 * @param  {string} password
 * @return {string} id_token
 */
export function GetB2cIdToken(username, password) {
  const state = GetState();
  SelfAsserted(state, username, password);
  const code = CombinedSigninAndSignup(state);
  return GetToken(code, state.codeVerifier);
}

/**
 * @typedef {object} b2cStateProperties
 * @property {string} csrfToken
 * @property {string} stateProperty
 * @property {string} codeVerifier
 *
 */

/**
 * Get the id token from Azure B2C
 * @function
 * @param {string} code
 * @returns {string} id_token
 */
const GetToken = (code, codeVerifier) =&amp;gt; {
  const url =
    `https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_id}` &amp;#43;
    `/oauth2/v2.0/token` &amp;#43;
    `?p=${B2CGraphSettings.B2C.user_flow_name}` &amp;#43;
    `&amp;amp;client_id=${B2CGraphSettings.B2C.client_id}` &amp;#43;
    `&amp;amp;grant_type=authorization_code` &amp;#43;
    `&amp;amp;scope=${B2CGraphSettings.B2C.scope}` &amp;#43;
    `&amp;amp;code=${code}` &amp;#43;
    `&amp;amp;redirect_uri=${B2CGraphSettings.B2C.redirect_url}` &amp;#43;
    `&amp;amp;code_verifier=${codeVerifier}`;

  const response = http.post(url, &amp;#39;&amp;#39;, {
    tags: {
      b2c_login: &amp;#39;GetToken&amp;#39;,
    },
  });

  return JSON.parse(response.body).id_token;
};

/**
 * Signs in the user using the CombinedSigninAndSignup policy
 * extraqct B2C code from response
 * @function
 * @param {b2cStateProperties} state
 * @returns {string} code
 */
const CombinedSigninAndSignup = (state) =&amp;gt; {
  const url =
    `https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_name}.onmicrosoft.com` &amp;#43;
    `/${B2CGraphSettings.B2C.user_flow_name}/api/CombinedSigninAndSignup/confirmed` &amp;#43;
    `?csrf_token=${state.csrfToken}` &amp;#43;
    `&amp;amp;rememberMe=false` &amp;#43;
    `&amp;amp;tx=StateProperties=${state.stateProperty}` &amp;#43;
    `&amp;amp;p=${B2CGraphSettings.B2C.user_flow_name}`;

  const response = http.get(url, &amp;#39;&amp;#39;, {
    tags: {
      b2c_login: &amp;#39;CombinedSigninAndSignup&amp;#39;,
    },
  });
  const codeRegex = &amp;#39;.*code=([^&amp;#34;]*)&amp;#39;;
  return response.url.match(codeRegex)[1];
};

/**
 * Signs in the user using the SelfAsserted policy
 * @function
 * @param {b2cStateProperties} state
 * @param {string} username
 * @param {string} password
 */
const SelfAsserted = (state, username, password) =&amp;gt; {
  const url =
    `https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_id}` &amp;#43;
    `/${B2CGraphSettings.B2C.user_flow_name}/SelfAsserted` &amp;#43;
    `?tx=StateProperties=${state.stateProperty}` &amp;#43;
    `&amp;amp;p=${B2CGraphSettings.B2C.user_flow_name}` &amp;#43;
    `&amp;amp;request_type=RESPONSE` &amp;#43;
    `&amp;amp;email=${username}` &amp;#43;
    `&amp;amp;password=${password}`;

  const params = {
    headers: {
      &amp;#39;X-CSRF-TOKEN&amp;#39;: `${state.csrfToken}`,
    },
    tags: {
      b2c_login: &amp;#39;SelfAsserted&amp;#39;,
    },
  };
  http.post(url, &amp;#39;&amp;#39;, params);
};

/**
 * Calls the B2C login page to get the state property
 * @function
 * @returns {b2cStateProperties} b2cState
 */
const GetState = () =&amp;gt; {
  const nonce = randomString(50);
  const challenge = crypto.sha256(nonce.toString(), &amp;#39;base64rawurl&amp;#39;);

  const url =
    `https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com` &amp;#43;
    `/${B2CGraphSettings.B2C.tenant_id}/oauth2/v2.0/authorize?` &amp;#43;
    `p=${B2CGraphSettings.B2C.user_flow_name}` &amp;#43;
    `&amp;amp;client_id=${B2CGraphSettings.B2C.client_id}` &amp;#43;
    `&amp;amp;nonce=${nonce}` &amp;#43;
    `&amp;amp;redirect_uri=${B2CGraphSettings.B2C.redirect_url}` &amp;#43;
    `&amp;amp;scope=${B2CGraphSettings.B2C.scope}` &amp;#43;
    `&amp;amp;response_type=code` &amp;#43;
    `&amp;amp;prompt=login` &amp;#43;
    `&amp;amp;code_challenge_method=S256` &amp;#43;
    `&amp;amp;code_challenge=${challenge}` &amp;#43;
    `&amp;amp;response_mode=fragment`;

  const response = http.get(url, &amp;#39;&amp;#39;, {
    tags: {
      b2c_login: &amp;#39;GetCookyAndState&amp;#39;,
    },
  });

  const vuJar = http.cookieJar();
  const responseCookies = vuJar.cookiesForURL(response.url);

  const b2cState = {};
  b2cState.codeVerifier = nonce;
  b2cState.csrfToken = responseCookies[&amp;#39;x-ms-cpim-csrf&amp;#39;][0];
  b2cState.stateProperty = response.body.match(&amp;#39;.*StateProperties=([^&amp;#34;]*)&amp;#39;)[1];
  return b2cState;
};

/**
 * Helper function to get the authorization header for a user
 * @param {user} user
 * @returns {object} httpsOptions
 */
export const GetAuthorizationHeaderForUser = (user) =&amp;gt; {
  const token = GetB2cIdToken(user.username, user.password);

  return {
    headers: {
      &amp;#39;Content-Type&amp;#39;: &amp;#39;application/json&amp;#39;,
      &amp;#39;Authorization&amp;#39;: &amp;#39;Bearer &amp;#39; &amp;#43; token,
    },
  };
};

export default function () {
  const token = GetB2cIdToken(&amp;#39;USERNAME&amp;#39;, &amp;#39;PASSWORD&amp;#39;);
  console.log(token);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;okta&#34;&gt;Okta&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import encoding from &amp;#39;k6/encoding&amp;#39;;

/**
 * Authenticate using OAuth against Okta
 * @function
 * @param  {string} oktaDomain - Okta domain to authenticate against (e.g. &amp;#39;k6.okta.com&amp;#39;)
 * @param  {string} authServerId - Authentication server identifier (default is &amp;#39;default&amp;#39;)
 * @param  {string} clientId - Generated by Okta automatically
 * @param  {string} clientSecret - Generated by Okta automatically
 * @param  {string} scope - Space-separated list of scopes
 * @param  {string|object} resource - Either a resource ID (as string) or an object containing username and password
 */
export function authenticateUsingOkta(
  oktaDomain,
  authServerId,
  clientId,
  clientSecret,
  scope,
  resource
) {
  if (authServerId === &amp;#39;undefined&amp;#39; || authServerId == &amp;#39;&amp;#39;) {
    authServerId = &amp;#39;default&amp;#39;;
  }
  const url = `https://${oktaDomain}/oauth2/${authServerId}/v1/token`;
  const requestBody = { scope: scope };
  let response;

  if (typeof resource == &amp;#39;string&amp;#39;) {
    requestBody[&amp;#39;grant_type&amp;#39;] = &amp;#39;client_credentials&amp;#39;;

    const encodedCredentials = encoding.b64encode(`${clientId}:${clientSecret}`);
    const params = {
      auth: &amp;#39;basic&amp;#39;,
      headers: {
        Authorization: `Basic ${encodedCredentials}`,
      },
    };

    response = http.post(url, requestBody, params);
  } else if (
    typeof resource == &amp;#39;object&amp;#39; &amp;amp;&amp;amp;
    resource.hasOwnProperty(&amp;#39;username&amp;#39;) &amp;amp;&amp;amp;
    resource.hasOwnProperty(&amp;#39;password&amp;#39;)
  ) {
    requestBody[&amp;#39;grant_type&amp;#39;] = &amp;#39;password&amp;#39;;
    requestBody[&amp;#39;username&amp;#39;] = resource.username;
    requestBody[&amp;#39;password&amp;#39;] = resource.password;
    requestBody[&amp;#39;client_id&amp;#39;] = clientId;
    requestBody[&amp;#39;client_secret&amp;#39;] = clientSecret;

    response = http.post(url, requestBody);
  } else {
    throw &amp;#39;resource should be either a string or an object containing username and password&amp;#39;;
  }

  return response.json();
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For a detailed example, please visit this article: &lt;a href=&#34;https://k6.io/blog/how-to-load-test-oauth-secured-apis-with-k6&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;How to Load Test OAuth secured APIs with k6?&lt;/a&gt;&lt;/p&gt;
]]></content><description>&lt;h1 id="oauth-authentication">OAuth Authentication&lt;/h1>
&lt;p>Scripting examples on how to use OAuth authentication in your load test.&lt;/p>
&lt;h2 id="oauth-authentication-1">OAuth authentication&lt;/h2>
&lt;p>The following examples take a set of arguments, shown in the function documentation, and returns the response body as JSON so that you can extract the token from.&lt;/p></description></item><item><title>Correlation and Dynamic Data</title><link>https://grafana.com/docs/k6/v2.3.x/examples/correlation-and-dynamic-data/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/correlation-and-dynamic-data/</guid><content><![CDATA[&lt;h1 id=&#34;correlation-and-dynamic-data&#34;&gt;Correlation and Dynamic Data&lt;/h1&gt;
&lt;p&gt;Scripting examples on how to correlate dynamic data in your test script. Correlation is often
required when using the HAR converter to generate your test script. This
is because those tools will capture session IDs, CSRF tokens, VIEWSTATE, wpnonce, and other
dynamic values from your specific session. These tokens typically expire very quickly. This
is one of the most common things that users will script for when testing user journeys across
websites or web apps.&lt;/p&gt;
&lt;h3 id=&#34;correlation&#34;&gt;Correlation&lt;/h3&gt;
&lt;p&gt;In a load testing scenario, correlation means extracting one or more values from the response
of one request and then reusing them in subsequent requests. Often, this could be getting
a token or some sort of ID necessary to fulfill a sequence of steps in a user journey.&lt;/p&gt;
&lt;p&gt;A 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/test-authoring/create-tests-from-recordings/&#34;&gt;recording&lt;/a&gt; will capture session data such as CSRF tokens,
VIEWSTATES, nonce, etc. This type of data is unlikely to be valid when
you run your test, meaning you&amp;rsquo;ll need to handle the extraction of this data from the HTML/form
to include it in subsequent requests. This issue is fairly common with any site that has forms
and can be handled with a little bit of scripting.&lt;/p&gt;
&lt;h3 id=&#34;extracting-valuestokens-from-a-json-response&#34;&gt;Extracting values/tokens from a JSON response&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

export default function () {
  // Make a request that returns some JSON data
  const reqHeaders = {
    Authorization: &amp;#39;Token abcdef0123456789&amp;#39;,
  };
  const res = http.get(&amp;#39;https://quickpizza.grafana.com/api/doughs&amp;#39;, {
    headers: reqHeaders,
  });

  // Extract data from that JSON data by first parsing it
  // using a call to &amp;#34;json()&amp;#34; and then accessing properties by
  // navigating the JSON data as a JS object with dot notation.
  const dough1 = res.json().doughs[0];
  check(dough1, {
    &amp;#39;dough1 1 has correct name&amp;#39;: (s) =&amp;gt; s.name === &amp;#39;Thin&amp;#39;,
    &amp;#39;dough1 1 has correct ID&amp;#39;: (s) =&amp;gt; s.ID === 1,
  });

  // Now we could use the &amp;#34;dough1&amp;#34; variable in subsequent requests...
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Relevant k6 APIs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/response/&#34;&gt;Response.json()&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/Web/JavaScript/Reference/Global_Objects/JSON/parse&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;JSON.parse()&lt;/a&gt;
(An alternative API that can be used for parsing JSON data)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;extracting-valuestokens-from-form-fields&#34;&gt;Extracting values/tokens from form fields&lt;/h3&gt;
&lt;p&gt;You can choose from two different approaches when deciding how to handle form submissions.
Either you use the higher-level 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/response/response-submitform/&#34;&gt;Response.submitForm([params])&lt;/a&gt; API
or you extract necessary hidden fields etc. and build a request yourself and then send it using the
appropriate &lt;code&gt;http.*&lt;/code&gt; family of APIs, like 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/post/&#34;&gt;http.post(url, [body], [params])&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;extracting-net-viewstates-csrf-tokens-and-other-hidden-input-fields&#34;&gt;Extracting .NET ViewStates, CSRF tokens and other hidden input fields&lt;/h4&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export default function () {
  // Request the page containing a form and save the response. This gives you access
  //to the response object, `res`.
  const res = http.get(&amp;#39;https://test.k6.io/my_messages.php&amp;#39;, { responseType: &amp;#39;text&amp;#39; });

  // Query the HTML for an input field named &amp;#34;redir&amp;#34;. We want the value or &amp;#34;redir&amp;#34;
  const elem = res.html().find(&amp;#39;input[name=redir]&amp;#39;);

  // Get the value of the attribute &amp;#34;value&amp;#34; and save it to a variable
  const val = elem.attr(&amp;#39;value&amp;#39;);

  // Now you can concatenate this extracted value in subsequent requests that require it.
  // ...
  // console.log() works when executing k6 scripts locally and is handy for debugging purposes
  console.log(&amp;#39;The value of the hidden field redir is: &amp;#39; &amp;#43; val);

  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;h3 id=&#34;-did-you-know&#34;&gt;⚠️ Did you know?&lt;/h3&gt;
&lt;p&gt;Take note if &lt;code&gt;discardResponseBodies&lt;/code&gt; is set to true in the options
section of your script. If it is, you can either make it &lt;code&gt;false&lt;/code&gt; or save the response per
request with &lt;code&gt;{&amp;quot;responseType&amp;quot;: &amp;quot;text&amp;quot;}&lt;/code&gt; as shown in the example.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relevant k6 APIs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/selection/selection-find/&#34;&gt;Selection.find(selector)&lt;/a&gt; (the &lt;a href=&#34;http://api.jquery.com/category/selectors/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;jQuery Selector API&lt;/a&gt;
docs are also a good resource on what possible selector queries can be made)&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/selection/selection-attr/&#34;&gt;Selection.attr(name)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;generic-extraction-of-valuestokens&#34;&gt;Generic extraction of values/tokens&lt;/h3&gt;
&lt;p&gt;Sometimes, responses may be neither JSON nor HTML, in which case the above extraction methods would not apply. In these situations, you would likely want to operate directly on the &lt;code&gt;Response.body&lt;/code&gt; string using a simple function capable of extracting a string at some known location. This is typically achieved by looking for the string &amp;ldquo;boundaries&amp;rdquo; immediately before (left) and after (right) the value needing extraction.&lt;/p&gt;
&lt;p&gt;The 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/&#34;&gt;jslib utils&lt;/a&gt; library contains an example of this kind of function,
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/findbetween/&#34;&gt;findBetween&lt;/a&gt;. The function uses the JavaScript built-in &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;String.indexOf&lt;/a&gt; and therefore doesn&amp;rsquo;t depend on potentially expensive regular-expression operations.&lt;/p&gt;
&lt;h4 id=&#34;extracting-a-valuetoken-using-findbetween&#34;&gt;Extracting a value/token using findBetween&lt;/h4&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { findBetween } from &amp;#39;https://jslib.k6.io/k6-utils/1.2.0/index.js&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;

export default function () {
  // This request returns XML:
  const res = http.get(&amp;#39;https://quickpizza.grafana.com/api/xml?color=green&amp;#39;);

  // Use findBetween to extract the first &amp;lt;value&amp;gt; tag encountered:
  const color = findBetween(res.body, &amp;#39;&amp;lt;value&amp;gt;&amp;#39;, &amp;#39;&amp;lt;/value&amp;gt;&amp;#39;);

  check(color, {
    &amp;#39;color is correct&amp;#39;: (t) =&amp;gt; t === &amp;#39;green&amp;#39;,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Relevant k6 APIs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/response/&#34;&gt;Response.body&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/findbetween/&#34;&gt;findBetween(content, left, right)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="correlation-and-dynamic-data">Correlation and Dynamic Data&lt;/h1>
&lt;p>Scripting examples on how to correlate dynamic data in your test script. Correlation is often
required when using the HAR converter to generate your test script. This
is because those tools will capture session IDs, CSRF tokens, VIEWSTATE, wpnonce, and other
dynamic values from your specific session. These tokens typically expire very quickly. This
is one of the most common things that users will script for when testing user journeys across
websites or web apps.&lt;/p></description></item><item><title>Data parameterization</title><link>https://grafana.com/docs/k6/v2.3.x/examples/data-parameterization/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/data-parameterization/</guid><content><![CDATA[&lt;h1 id=&#34;data-parameterization&#34;&gt;Data parameterization&lt;/h1&gt;
&lt;!-- md-k6:skipall --&gt;
&lt;p&gt;&lt;em&gt;Data parameterization&lt;/em&gt; is the process of turning test values into reusable parameters, for example, through variables and shared arrays.&lt;/p&gt;
&lt;p&gt;This page gives some examples of how to parameterize data in a test script.
Parameterization is typically necessary when Virtual Users (VUs) make a POST, PUT, or PATCH request in a test.
You can also use parameterization when you need to add test data from a separate file.&lt;/p&gt;
&lt;p&gt;Parameterization helps to prevent server-side caching from impacting your load test, which makes your tests more realistic.&lt;/p&gt;
&lt;h2 id=&#34;performance-implications-of-sharedarray&#34;&gt;Performance implications of &lt;code&gt;SharedArray&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Each VU in k6 is a separate JS VM. To prevent multiple copies of the whole data file,

    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-data/sharedarray/&#34;&gt;SharedArray&lt;/a&gt; was added. It does have some CPU overhead in accessing elements compared to a normal non shared
array, but the difference is negligible compared to the time it takes to make requests. This becomes
even less of an issue compared to not using it with large files, as k6 would otherwise use too much memory to run, which might lead to your script not being able to run at all or aborting in the middle if the system resources are exhausted.&lt;/p&gt;
&lt;p&gt;For example, the Cloud service allocates 8GB of memory for every 300 VUs. So if your files are large
enough and you are not using 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-data/sharedarray/&#34;&gt;SharedArray&lt;/a&gt;, that might mean that your script will run out of memory at
some point. Additionally even if there is enough memory, k6 has a garbage collector (as it&amp;rsquo;s written
in golang) and it will walk through all accessible objects (including JS ones) and figure out which
need to be garbage collected. For big JS arrays copied hundreds of times this adds quite a lot of
additional work.&lt;/p&gt;
&lt;p&gt;A note on performance characteristics of &lt;code&gt;SharedArray&lt;/code&gt; can be found within its 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-data/sharedarray/#performance-characteristics&#34;&gt;API documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;from-a-json-file&#34;&gt;From a JSON file&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;users&amp;#34;: [
    { &amp;#34;username&amp;#34;: &amp;#34;test&amp;#34;, &amp;#34;password&amp;#34;: &amp;#34;qwerty&amp;#34; },
    { &amp;#34;username&amp;#34;: &amp;#34;test&amp;#34;, &amp;#34;password&amp;#34;: &amp;#34;qwerty&amp;#34; }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { SharedArray } from &amp;#39;k6/data&amp;#39;;
// not using SharedArray here will mean that the code in the function call (that is what loads and
// parses the json) will be executed per each VU which also means that there will be a complete copy
// per each VU
const data = new SharedArray(&amp;#39;some data name&amp;#39;, function () {
  return JSON.parse(open(&amp;#39;./data.json&amp;#39;)).users;
});

export default function () {
  const user = data[0];
  console.log(data[0].username);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;from-a-csv-file&#34;&gt;From a CSV file&lt;/h2&gt;
&lt;p&gt;k6 doesn&amp;rsquo;t parse CSV files natively, but you can use an external library, &lt;a href=&#34;https://www.papaparse.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Papa Parse&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can download the library and import it locally like this:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import papaparse from &amp;#39;./papaparse.js&amp;#39;;
import { SharedArray } from &amp;#39;k6/data&amp;#39;;
// not using SharedArray here will mean that the code in the function call (that is what loads and
// parses the csv) will be executed per each VU which also means that there will be a complete copy
// per each VU
const csvData = new SharedArray(&amp;#39;another data name&amp;#39;, function () {
  // Load CSV file and parse it using Papa Parse
  return papaparse.parse(open(&amp;#39;./data.csv&amp;#39;), { header: true }).data;
});

export default function () {
  // ...
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or you can grab it directly from &lt;a href=&#34;https://jslib.k6.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;jslib.k6.io&lt;/a&gt; like this.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import papaparse from &amp;#39;https://jslib.k6.io/papaparse/5.1.1/index.js&amp;#39;;
import { SharedArray } from &amp;#39;k6/data&amp;#39;;

// not using SharedArray here will mean that the code in the function call (that is what loads and
// parses the csv) will be executed per each VU which also means that there will be a complete copy
// per each VU
const csvData = new SharedArray(&amp;#39;another data name&amp;#39;, function () {
  // Load CSV file and parse it using Papa Parse
  return papaparse.parse(open(&amp;#39;./data.csv&amp;#39;), { header: true }).data;
});

export default function () {
  // ...
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;rsquo;s an example using Papa Parse to parse a CSV file of username/password pairs and using that
data to login to the test.k6.io test site:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;/*  Where contents of data.csv is:
username,password
admin,123
test_user,1234
*/
import http from &amp;#39;k6/http&amp;#39;;
import { check, sleep } from &amp;#39;k6&amp;#39;;
import { SharedArray } from &amp;#39;k6/data&amp;#39;;
import papaparse from &amp;#39;https://jslib.k6.io/papaparse/5.1.1/index.js&amp;#39;;

// not using SharedArray here will mean that the code in the function call (that is what loads and
// parses the csv) will be executed per each VU which also means that there will be a complete copy
// per each VU
const csvData = new SharedArray(&amp;#39;another data name&amp;#39;, function () {
  // Load CSV file and parse it using Papa Parse
  return papaparse.parse(open(&amp;#39;./data.csv&amp;#39;), { header: true }).data;
});

export default function () {
  // Now you can use the CSV data in your test logic below.
  // Below are some examples of how you can access the CSV data.

  // Loop through all username/password pairs
  for (const userPwdPair of csvData) {
    console.log(JSON.stringify(userPwdPair));
  }

  // Pick a random username/password pair
  const randomUser = csvData[Math.floor(Math.random() * csvData.length)];
  console.log(&amp;#39;Random user: &amp;#39;, JSON.stringify(randomUser));

  const params = {
    login: randomUser.username,
    password: randomUser.password,
  };
  console.log(&amp;#39;Random user: &amp;#39;, JSON.stringify(params));

  const res = http.post(&amp;#39;https://test.k6.io/login.php&amp;#39;, params);
  check(res, {
    &amp;#39;login succeeded&amp;#39;: (r) =&amp;gt; r.status === 200 &amp;amp;&amp;amp; r.body.indexOf(&amp;#39;successfully authorized&amp;#39;) !== -1,
  });

  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;retrieving-unique-data&#34;&gt;Retrieving unique data&lt;/h2&gt;
&lt;p&gt;It is often a requirement not to use the same data more than once in a test. With the help of 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-execution/&#34;&gt;k6/execution&lt;/a&gt;, which includes a property &lt;code&gt;scenario.iterationInTest&lt;/code&gt;, you can retrieve unique rows from your dataset.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;&lt;code&gt;scenario.iterationInTest&lt;/code&gt; property is unique &lt;em&gt;per scenario&lt;/em&gt;, not the overall test. That means if you have multiple scenarios in your test you might need to split your data per scenario.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { SharedArray } from &amp;#39;k6/data&amp;#39;;
import { scenario } from &amp;#39;k6/execution&amp;#39;;

const data = new SharedArray(&amp;#39;users&amp;#39;, function () {
  return JSON.parse(open(&amp;#39;./data.json&amp;#39;)).users;
});

export const options = {
  scenarios: {
    &amp;#39;use-all-the-data&amp;#39;: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      vus: 10,
      iterations: data.length,
      maxDuration: &amp;#39;1h&amp;#39;,
    },
  },
};

export default function () {
  // this is unique even in the cloud
  const user = data[scenario.iterationInTest];
  console.log(`user: ${JSON.stringify(user)}`);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Alternatively, if your use case requires using a unique dataset per VU, you could leverage a property called &lt;code&gt;vu.idInTest&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the following example we&amp;rsquo;re going to be using &lt;code&gt;per-vu-iterations&lt;/code&gt; executor to ensure that every VU completes
a fixed amount of iterations.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { sleep } from &amp;#39;k6&amp;#39;;
import { SharedArray } from &amp;#39;k6/data&amp;#39;;
import { vu } from &amp;#39;k6/execution&amp;#39;;

const users = new SharedArray(&amp;#39;users&amp;#39;, function () {
  return JSON.parse(open(&amp;#39;./data.json&amp;#39;)).users;
});

export const options = {
  scenarios: {
    login: {
      executor: &amp;#39;per-vu-iterations&amp;#39;,
      vus: users.length,
      iterations: 20,
      maxDuration: &amp;#39;1h30m&amp;#39;,
    },
  },
};

export default function () {
  // VU identifiers are one-based and arrays are zero-based, thus we need - 1
  console.log(`Users name: ${users[vu.idInTest - 1].username}`);
  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you have a large dataset and want to make sure no two VUs use the same value in the dataset at the same time, while keeping a fixed number of VUs, use the modulo operator (&lt;code&gt;%&lt;/code&gt;) with the global iteration index. This gives you a round-robin assignment over the dataset and avoids collisions during a run.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { sleep } from &amp;#39;k6&amp;#39;;
import { SharedArray } from &amp;#39;k6/data&amp;#39;;
import { scenario } from &amp;#39;k6/execution&amp;#39;;

const users = new SharedArray(&amp;#39;users&amp;#39;, function () {
  return JSON.parse(open(&amp;#39;./data.json&amp;#39;)).users;
});

const vus = 100;
export const options = {
  scenarios: {
    login: {
      executor: &amp;#39;constant-vus&amp;#39;,
      vus: vus,
      duration: &amp;#39;1h30m&amp;#39;,
    },
  },
};

export default function () {
  console.log(`Users name: ${users[scenario.iterationInTest % vus].username}`);
  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;generating-data-using-fakerjs&#34;&gt;Generating data using faker.js&lt;/h2&gt;
&lt;p&gt;The following articles show how to use faker.js in k6 to generate realistic data during the test execution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://dev.to/k6/performance-testing-with-generated-data-using-k6-and-faker-2e&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Performance Testing with Generated Data using k6 and Faker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://farhan-labib.medium.com/load-testing-made-easy-with-k6-using-faker-library-and-csv-files-c997d48fb6e2&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Load Testing Made Easy with K6: Using Faker Library and CSV Files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="data-parameterization">Data parameterization&lt;/h1>
&lt;!-- md-k6:skipall -->
&lt;p>&lt;em>Data parameterization&lt;/em> is the process of turning test values into reusable parameters, for example, through variables and shared arrays.&lt;/p>
&lt;p>This page gives some examples of how to parameterize data in a test script.
Parameterization is typically necessary when Virtual Users (VUs) make a POST, PUT, or PATCH request in a test.
You can also use parameterization when you need to add test data from a separate file.&lt;/p></description></item><item><title>Parse HTML</title><link>https://grafana.com/docs/k6/v2.3.x/examples/parse-html/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/parse-html/</guid><content><![CDATA[&lt;h1 id=&#34;parse-html&#34;&gt;Parse HTML&lt;/h1&gt;
&lt;p&gt;Examples parsing HTML content. Use the &lt;code&gt;k6/html&lt;/code&gt; module for HTML parsing.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/selection/&#34;&gt;Selection&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Class&lt;/td&gt;
              &lt;td&gt;A jQuery-like API for accessing HTML DOM elements.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/element/&#34;&gt;Element&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Class&lt;/td&gt;
              &lt;td&gt;An HTML DOM element as returned by the Selection API.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/parsehtml/&#34;&gt;parseHTML(src)&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;function&lt;/td&gt;
              &lt;td&gt;Parse an HTML string and populate a Selection object.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { parseHTML } from &amp;#39;k6/html&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;

export default function () {
  const res = http.get(&amp;#39;https://k6.io&amp;#39;);
  const doc = parseHTML(res.body); // equivalent to res.html()
  const pageTitle = doc.find(&amp;#39;head title&amp;#39;).text();
  const langAttr = doc.find(&amp;#39;html&amp;#39;).attr(&amp;#39;lang&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { parseHTML } from &amp;#39;k6/html&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export default function () {
  const content = `
&amp;lt;dl&amp;gt;
  &amp;lt;dt id=&amp;#34;term-1&amp;#34;&amp;gt;Value term 1&amp;lt;/dt&amp;gt;
  &amp;lt;dt id=&amp;#34;term-2&amp;#34;&amp;gt;Value term 2&amp;lt;/dt&amp;gt;
&amp;lt;/dl&amp;gt;
  `;
  const sel = parseHTML(content).find(&amp;#39;dl&amp;#39;).children();

  const el1 = sel.get(0);
  const el2 = sel.get(1);

  console.log(el1.nodeName());
  console.log(el1.id());
  console.log(el1.textContent());

  console.log(el2.nodeName());
  console.log(el2.id());
  console.log(el2.textContent());

  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="parse-html">Parse HTML&lt;/h1>
&lt;p>Examples parsing HTML content. Use the &lt;code>k6/html&lt;/code> module for HTML parsing.&lt;/p>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-html/selection/">Selection&lt;/a>&lt;/td>
&lt;td>Class&lt;/td>
&lt;td>A jQuery-like API for accessing HTML DOM elements.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-html/element/">Element&lt;/a>&lt;/td>
&lt;td>Class&lt;/td>
&lt;td>An HTML DOM element as returned by the Selection API.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-html/parsehtml/">parseHTML(src)&lt;/a>&lt;/td>
&lt;td>function&lt;/td>
&lt;td>Parse an HTML string and populate a Selection object.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { parseHTML } from &amp;#39;k6/html&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;
export default function () {
const res = http.get(&amp;#39;https://k6.io&amp;#39;);
const doc = parseHTML(res.body); // equivalent to res.html()
const pageTitle = doc.find(&amp;#39;head title&amp;#39;).text();
const langAttr = doc.find(&amp;#39;html&amp;#39;).attr(&amp;#39;lang&amp;#39;);
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { parseHTML } from &amp;#39;k6/html&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;
export default function () {
const content = `
&amp;lt;dl&amp;gt;
&amp;lt;dt id=&amp;#34;term-1&amp;#34;&amp;gt;Value term 1&amp;lt;/dt&amp;gt;
&amp;lt;dt id=&amp;#34;term-2&amp;#34;&amp;gt;Value term 2&amp;lt;/dt&amp;gt;
&amp;lt;/dl&amp;gt;
`;
const sel = parseHTML(content).find(&amp;#39;dl&amp;#39;).children();
const el1 = sel.get(0);
const el2 = sel.get(1);
console.log(el1.nodeName());
console.log(el1.id());
console.log(el1.textContent());
console.log(el2.nodeName());
console.log(el2.id());
console.log(el2.textContent());
sleep(1);
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div></description></item><item><title>HTML Forms</title><link>https://grafana.com/docs/k6/v2.3.x/examples/html-forms/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/html-forms/</guid><content><![CDATA[&lt;h1 id=&#34;html-forms&#34;&gt;HTML Forms&lt;/h1&gt;
&lt;p&gt;Scripting example on how to handle HTML forms.&lt;/p&gt;
&lt;p&gt;In many cases using the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/selection/&#34;&gt;Selection&lt;/a&gt; API (jQuery API clone) to interact with HTML data is enough, but for some use cases, like with forms, we can make things easier providing a higher-level API like the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/response/response-submitform/&#34;&gt;Response.submitForm( [params] )&lt;/a&gt; API.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export default function () {
  // Request page containing a form
  let res = http.get(&amp;#39;https://quickpizza.grafana.com/admin&amp;#39;);

  // Now, submit form setting/overriding some fields of the form
  res = res.submitForm({
    formSelector: &amp;#39;form&amp;#39;,
    fields: { username: &amp;#39;admin&amp;#39;, password: &amp;#39;admin&amp;#39; },
  });
  sleep(3);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Relevant k6 APIs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/response/response-submitform/&#34;&gt;Response.submitForm([params])&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-html/selection/selection-find/&#34;&gt;Selection.find(selector)&lt;/a&gt;
(the &lt;a href=&#34;http://api.jquery.com/category/selectors/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;jQuery Selector API&lt;/a&gt; docs are also a good
resource on what possible selector queries can be made)&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="html-forms">HTML Forms&lt;/h1>
&lt;p>Scripting example on how to handle HTML forms.&lt;/p>
&lt;p>In many cases using the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-html/selection/">Selection&lt;/a> API (jQuery API clone) to interact with HTML data is enough, but for some use cases, like with forms, we can make things easier providing a higher-level API like the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-http/response/response-submitform/">Response.submitForm( [params] )&lt;/a> API.&lt;/p></description></item><item><title>Cookies Example</title><link>https://grafana.com/docs/k6/v2.3.x/examples/cookies-example/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/cookies-example/</guid><content><![CDATA[&lt;h1 id=&#34;cookies-example&#34;&gt;Cookies Example&lt;/h1&gt;
&lt;p&gt;Scripting examples on how you can interact with cookies during your load test if required.&lt;/p&gt;
&lt;h2 id=&#34;cookies&#34;&gt;Cookies&lt;/h2&gt;
&lt;p&gt;As HTTP is a stateless protocol, cookies are used by server-side applications to persist data
on client machines. This is used more or less everywhere on the web, commonly for user session
tracking purposes. In k6 cookies are managed automatically by default, however, there are use
cases where access to read and manipulate cookies are required.&lt;/p&gt;
&lt;h2 id=&#34;from-the-response-headers&#34;&gt;From the response headers&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check, group } from &amp;#39;k6&amp;#39;;

export default function () {
  // Since this request redirects the `res.cookies` property won&amp;#39;t contain the cookies
  const res = http.post(&amp;#39;https://quickpizza.grafana.com/api/cookies?name1=value1&amp;amp;name2=value2&amp;#39;);
  check(res, {
    &amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
  });

  // Make sure cookies have been added to VU cookie jar
  const vuJar = http.cookieJar();
  const cookiesForURL = vuJar.cookiesForURL(res.url);
  check(null, {
    &amp;#34;vu jar has cookie &amp;#39;name1&amp;#39;&amp;#34;: () =&amp;gt; cookiesForURL.name1.length &amp;gt; 0,
    &amp;#34;vu jar has cookie &amp;#39;name2&amp;#39;&amp;#34;: () =&amp;gt; cookiesForURL.name2.length &amp;gt; 0,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;log-all-the-cookies-in-a-response&#34;&gt;Log all the cookies in a response&lt;/h2&gt;
&lt;blockquote&gt;
&lt;h3 id=&#34;-note-that-this-only-works-when-using-k6-locally&#34;&gt;⚠️ Note that this only works when using k6 locally&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;console.log()&lt;/code&gt; family of APIs are currently only usable when running k6 locally.
When running k6 tests with LoadImpact Cloud Execution the logs will be discarded.&lt;/p&gt;&lt;/blockquote&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;// Example showing two methods how to log all cookies (with attributes) from a HTTP response.

import http from &amp;#39;k6/http&amp;#39;;

function logCookie(cookie) {
  // Here we log the name and value of the cookie along with additional attributes.
  // For full list of attributes see: https:///grafana.com/docs/k6/using-k6/cookies#properties-of-a-response-cookie-object
  console.log(
    `${cookie.name}: ${cookie.value}\n\tdomain: ${cookie.domain}\n\tpath: ${cookie.path}\n\texpires: ${cookie.expires}\n\thttpOnly: ${cookie.http_only}`
  );
}

export default function () {
  const res = http.get(&amp;#39;https://www.google.com/&amp;#39;);

  // Method 1: Use for-loop and check for non-inherited properties
  for (const name in res.cookies) {
    if (res.cookies.hasOwnProperty(name) !== undefined) {
      logCookie(res.cookies[name][0]);
    }
  }

  // Method 2: Use ES6 Map to loop over Object entries
  new Map(Object.entries(res.cookies)).forEach((v, k) =&amp;gt; logCookie(v[0]));
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;setting-a-cookie-in-the-vu-cookie-jar&#34;&gt;Setting a cookie in the VU cookie jar&lt;/h2&gt;
&lt;p&gt;To set a cookie that should be sent with every request matching a particular domain, path, etc.
you&amp;rsquo;d do something like this:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

export default function () {
  // Get VU cookie jar and add a cookie to it providing the parameters
  // that a request must match (domain, path, HTTPS or not etc.)
  // to have the cookie attached to it when sent to the server.
  const jar = http.cookieJar();
  jar.set(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;, &amp;#39;my_cookie&amp;#39;, &amp;#39;hello world&amp;#39;, {
    domain: &amp;#39;quickpizza.grafana.com&amp;#39;,
    path: &amp;#39;/api/cookies&amp;#39;,
    secure: true,
    max_age: 600,
  });

  // As the following request is matching the above cookie in terms of domain,
  // path, HTTPS (secure) and will happen within the specified &amp;#34;age&amp;#34; limit, the
  // cookie will be attached to this request.
  const res = http.get(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;);
  check(res, {
    &amp;#39;has status 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#34;has cookie &amp;#39;my_cookie&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie !== null,
    &amp;#39;cookie has correct value&amp;#39;: (r) =&amp;gt; r.json().cookies.my_cookie == &amp;#39;hello world&amp;#39;,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;delete-a-cookie-in-the-vu-cookie-jar&#34;&gt;Delete a cookie in the VU cookie jar&lt;/h2&gt;
&lt;p&gt;To delete a cookie in the jar for a specific URL and name, use the &lt;code&gt;delete&lt;/code&gt; method.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

export default function () {
  const jar = http.cookieJar();
  jar.set(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;, &amp;#39;my_cookie_1&amp;#39;, &amp;#39;hello world_1&amp;#39;);
  jar.set(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;, &amp;#39;my_cookie_2&amp;#39;, &amp;#39;hello world_2&amp;#39;);

  const res1 = http.get(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;);
  check(res1, {
    &amp;#39;res1 has status 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#34;res1 has cookie &amp;#39;my_cookie_1&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie_1 !== null,
    &amp;#39;res1 cookie has correct value_1&amp;#39;: (r) =&amp;gt; r.json().cookies.my_cookie_1 == &amp;#39;hello world_1&amp;#39;,
    &amp;#34;res1 has cookie &amp;#39;my_cookie_2&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie_2 !== null,
    &amp;#39;res1 cookie has correct value_2&amp;#39;: (r) =&amp;gt; r.json().cookies.my_cookie_2 == &amp;#39;hello world_2&amp;#39;,
  });

  jar.delete(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;, &amp;#39;my_cookie_1&amp;#39;);

  const res2 = http.get(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;);
  check(res2, {
    &amp;#39;res2 has status 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#34;res2 hasn&amp;#39;t cookie &amp;#39;my_cookie_1&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie_1 == null,
    &amp;#34;res2 has cookie &amp;#39;my_cookie_2&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie_2 !== null,
    &amp;#39;res2 cookie has correct value_2&amp;#39;: (r) =&amp;gt; r.json().cookies.my_cookie_2 == &amp;#39;hello world_2&amp;#39;,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;clear-all-cookies-in-the-vu-cookie-jar&#34;&gt;Clear all cookies in the VU cookie jar&lt;/h2&gt;
&lt;p&gt;To clear all cookies in the jar by specifying url, use the &lt;code&gt;clear&lt;/code&gt; method.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

export default function () {
  const jar = http.cookieJar();
  jar.set(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;, &amp;#39;my_cookie&amp;#39;, &amp;#39;hello world&amp;#39;);
  const res1 = http.get(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;);
  check(res1, {
    &amp;#39;has status 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#34;has cookie &amp;#39;my_cookie&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie !== null,
    &amp;#39;cookie has correct value&amp;#39;: (r) =&amp;gt; r.json().cookies.my_cookie == &amp;#39;hello world&amp;#39;,
  });

  jar.clear(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;);

  const res2 = http.get(&amp;#39;https://quickpizza.grafana.com/api/cookies&amp;#39;);
  check(res2, {
    &amp;#39;has status 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#34;hasn&amp;#39;t cookie &amp;#39;my_cookie&amp;#39;&amp;#34;: (r) =&amp;gt; r.json().cookies.my_cookie == null,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Relevant k6 APIs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/cookiejar-method/&#34;&gt;http.cookieJar()&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/cookiejar/&#34;&gt;http.CookieJar&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/cookiejar/cookiejar-set/&#34;&gt;set(url, name, value, [options])&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/cookiejar/cookiejar-delete/&#34;&gt;delete(url, name)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/cookiejar/cookiejar-clear/&#34;&gt;clear(url)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="cookies-example">Cookies Example&lt;/h1>
&lt;p>Scripting examples on how you can interact with cookies during your load test if required.&lt;/p>
&lt;h2 id="cookies">Cookies&lt;/h2>
&lt;p>As HTTP is a stateless protocol, cookies are used by server-side applications to persist data
on client machines. This is used more or less everywhere on the web, commonly for user session
tracking purposes. In k6 cookies are managed automatically by default, however, there are use
cases where access to read and manipulate cookies are required.&lt;/p></description></item><item><title>Data Uploads</title><link>https://grafana.com/docs/k6/v2.3.x/examples/data-uploads/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/data-uploads/</guid><content><![CDATA[&lt;h1 id=&#34;data-uploads&#34;&gt;Data Uploads&lt;/h1&gt;
&lt;p&gt;Example to execute a load test that will upload a file to the System Under Test (SUT).&lt;/p&gt;
&lt;h2 id=&#34;the-open-function&#34;&gt;The open() function&lt;/h2&gt;
&lt;p&gt;Using the built-in function 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/init-context/open/&#34;&gt;&lt;code&gt;open()&lt;/code&gt;&lt;/a&gt;,
we can read the contents of a file given a filename or URL.&lt;/p&gt;
&lt;p&gt;Below is a simple example showing how to load the contents of a local file &lt;code&gt;data.json&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;my_key&amp;#34;: &amp;#34;has a value&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;const data = JSON.parse(open(&amp;#39;./data.json&amp;#39;));

export default function () {
  console.log(data.my_key);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you want to open a binary file you need to pass in &lt;code&gt;&amp;quot;b&amp;quot;&lt;/code&gt; as the second argument.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;const binFile = open(&amp;#39;./image.png&amp;#39;, &amp;#39;b&amp;#39;);

export default function () {
  //...
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;multipart-request-uploading-a-file&#34;&gt;Multipart request (uploading a file)&lt;/h2&gt;
&lt;p&gt;Now that you know how to load a local file, let&amp;rsquo;s look at a script that creates a POST request
to upload this data to an API endpoint along with a regular text field (&lt;code&gt;field&lt;/code&gt; in the example
below):&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

const binFile = open(&amp;#39;/path/to/file.bin&amp;#39;, &amp;#39;b&amp;#39;);

export default function () {
  const data = {
    field: &amp;#39;this is a standard form field&amp;#39;,
    file: http.file(binFile, &amp;#39;test.bin&amp;#39;),
  };

  const res = http.post(&amp;#39;https://example.com/upload&amp;#39;, data);
  sleep(3);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the example above we use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/file/&#34;&gt;http.file()&lt;/a&gt;
API to wrap the file contents in a 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/filedata/&#34;&gt;FileData&lt;/a&gt; object.
When passing a JS object as the body parameter to 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/post/&#34;&gt;http.post()&lt;/a&gt;,
or any of the other HTTP request functions, where one of the property values is a

    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/filedata/&#34;&gt;FileData&lt;/a&gt; a multipart request will be constructed
and sent.&lt;/p&gt;
&lt;h3 id=&#34;relevant-k6-apis&#34;&gt;Relevant k6 APIs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/init-context/open/&#34;&gt;open(filePath, [mode])&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/file/&#34;&gt;http.file(data, [filename], [contentType])&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;advanced-multipart-request&#34;&gt;Advanced multipart request&lt;/h2&gt;
&lt;p&gt;The previous multipart request example has some limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s not possible to assemble the parts in a specific order, because of the
unordered nature of JS objects when they&amp;rsquo;re converted to Golang maps, which k6 uses internally.
Uploading files in a specific order is a requirement for some APIs (e.g. AWS S3).&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s not possible to upload multiple files as part of the same form field, because
JS object keys must be unique.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To address this we suggest using the &lt;a href=&#34;https://jslib.k6.io/formdata/0.0.2/index.js&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;FormData&lt;/code&gt; polyfill for k6&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of uploading several binary files and a text file using the polyfill:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;
import { FormData } from &amp;#39;https://jslib.k6.io/formdata/0.0.2/index.js&amp;#39;;

const img1 = open(&amp;#39;/path/to/image1.png&amp;#39;, &amp;#39;b&amp;#39;);
const img2 = open(&amp;#39;/path/to/image2.jpg&amp;#39;, &amp;#39;b&amp;#39;);
const txt = open(&amp;#39;/path/to/text.txt&amp;#39;);

export default function () {
  const fd = new FormData();
  fd.append(&amp;#39;someTextField&amp;#39;, &amp;#39;someValue&amp;#39;);
  fd.append(&amp;#39;aBinaryFile&amp;#39;, {
    data: new Uint8Array(img1).buffer,
    filename: &amp;#39;logo.png&amp;#39;,
    content_type: &amp;#39;image/png&amp;#39;,
  });
  fd.append(&amp;#39;anotherTextField&amp;#39;, &amp;#39;anotherValue&amp;#39;);
  fd.append(&amp;#39;images&amp;#39;, http.file(img1, &amp;#39;image1.png&amp;#39;, &amp;#39;image/png&amp;#39;));
  fd.append(&amp;#39;images&amp;#39;, http.file(img2, &amp;#39;image2.jpg&amp;#39;, &amp;#39;image/jpeg&amp;#39;));
  fd.append(&amp;#39;text&amp;#39;, http.file(txt, &amp;#39;text.txt&amp;#39;, &amp;#39;text/plain&amp;#39;));

  const res = http.post(&amp;#39;https://quickpizza.grafana.com/api/post&amp;#39;, fd.body(), {
    headers: { &amp;#39;Content-Type&amp;#39;: &amp;#39;multipart/form-data; boundary=&amp;#39; &amp;#43; fd.boundary },
  });
  check(res, {
    &amp;#39;is status 200&amp;#39;: (r) =&amp;gt; r.status === 200,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Both binary files will be uploaded under the &lt;code&gt;images&lt;/code&gt; form field, and the text file
will appear last in the request under the &lt;code&gt;text&lt;/code&gt; form field.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s required to specify the multipart boundary in the &lt;code&gt;Content-Type&lt;/code&gt; header,
so you must assemble the header manually as shown.&lt;/li&gt;
&lt;li&gt;Blob is not supported or implemented. For the same functionality, use
a simple object with the fields &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;content_type&lt;/code&gt; (defaulting to &amp;ldquo;application/octet-stream&amp;rdquo;) and optionally
&lt;code&gt;filename&lt;/code&gt; as shown for &lt;code&gt;aBinaryFile&lt;/code&gt; above.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- md-k6:skipall --&gt;
]]></content><description>&lt;h1 id="data-uploads">Data Uploads&lt;/h1>
&lt;p>Example to execute a load test that will upload a file to the System Under Test (SUT).&lt;/p>
&lt;h2 id="the-open-function">The open() function&lt;/h2>
&lt;p>Using the built-in function
&lt;a href="/docs/k6/v2.3.x/javascript-api/init-context/open/">&lt;code>open()&lt;/code>&lt;/a>,
we can read the contents of a file given a filename or URL.&lt;/p></description></item><item><title>API CRUD Operations</title><link>https://grafana.com/docs/k6/v2.3.x/examples/api-crud-operations/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/api-crud-operations/</guid><content><![CDATA[&lt;h1 id=&#34;api-crud-operations&#34;&gt;API CRUD Operations&lt;/h1&gt;
&lt;p&gt;The examples showcase the testing of CRUD operations on a REST API.&lt;/p&gt;
&lt;p&gt;CRUD refers to the basic operations in a database: Create, Read, Update, and Delete. We can map these operations to HTTP methods in REST APIs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Create&lt;/em&gt;: HTTP &lt;code&gt;POST&lt;/code&gt; operation to create a new resource.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Read&lt;/em&gt;: HTTP &lt;code&gt;GET&lt;/code&gt; to retrieve a resource.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Update&lt;/em&gt;: HTTP &lt;code&gt;PUT&lt;/code&gt;or &lt;code&gt;PATCH&lt;/code&gt; to change an existing resource.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Delete&lt;/em&gt;: HTTP &lt;code&gt;DELETE&lt;/code&gt; to remove a resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This document has two examples, one that uses the core k6 APIs (&lt;code&gt;k6/http&lt;/code&gt; and &lt;code&gt;checks&lt;/code&gt;) and another to show the more recent APIs 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/httpx/&#34;&gt;&lt;code&gt;httpx&lt;/code&gt;&lt;/a&gt; and 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/k6chaijs/&#34;&gt;&lt;code&gt;k6chaijs&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;test-steps&#34;&gt;Test steps&lt;/h2&gt;
&lt;p&gt;In the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/test-lifecycle/#setup-and-teardown-stages&#34;&gt;setup() stage&lt;/a&gt; we create a user for &lt;a href=&#34;https://quickpizza.grafana.com&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;QuickPizza&lt;/a&gt;. We then retrieve and return a bearer token to authenticate the next CRUD requests.&lt;/p&gt;
&lt;p&gt;The steps implemented in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/test-lifecycle/#the-vu-stage&#34;&gt;VU stage&lt;/a&gt; are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Create&lt;/em&gt; a new resource, a pizza rating.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Read&lt;/em&gt; the list of ratings.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Update&lt;/em&gt; the rating&amp;rsquo;s stars (e.g. to 5 stars) and &lt;em&gt;read&lt;/em&gt; the rating to confirm the update operation.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Delete&lt;/em&gt; the rating resource.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;core-k6-apis-example&#34;&gt;Core k6 APIs example&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check, group, fail } from &amp;#39;k6&amp;#39;;

export const options = {
  vus: 1,
  iterations: 1,
};

// Create a random string of given length
function randomString(length, charset = &amp;#39;&amp;#39;) {
  if (!charset) charset = &amp;#39;abcdefghijklmnopqrstuvwxyz&amp;#39;;
  let res = &amp;#39;&amp;#39;;
  while (length--) res &amp;#43;= charset[(Math.random() * charset.length) | 0];
  return res;
}

const USERNAME = `${randomString(10)}@example.com`; // Set your own email or `${randomString(10)}@example.com`;
const PASSWORD = &amp;#39;secret&amp;#39;;

const BASE_URL = &amp;#39;https://quickpizza.grafana.com&amp;#39;;

// Register a new user and retrieve authentication token for subsequent API requests
export function setup() {
  const res = http.post(
    `${BASE_URL}/api/users`,
    JSON.stringify({
      username: USERNAME,
      password: PASSWORD,
    })
  );

  check(res, { &amp;#39;created user&amp;#39;: (r) =&amp;gt; r.status === 201 });

  const loginRes = http.post(
    `${BASE_URL}/api/users/token/login`,
    JSON.stringify({
      username: USERNAME,
      password: PASSWORD,
    })
  );

  const authToken = loginRes.json(&amp;#39;token&amp;#39;);
  check(authToken, { &amp;#39;logged in successfully&amp;#39;: () =&amp;gt; authToken.length &amp;gt; 0 });

  return authToken;
}

export default function (authToken) {
  // set the authorization header on the session for the subsequent requests
  const requestConfigWithTag = (tag) =&amp;gt; ({
    headers: {
      Authorization: `Bearer ${authToken}`,
    },
    tags: Object.assign(
      {},
      {
        name: &amp;#39;PrivateRatings&amp;#39;,
      },
      tag
    ),
  });

  let URL = `${BASE_URL}/api/ratings`;

  group(&amp;#39;01. Create a new rating&amp;#39;, () =&amp;gt; {
    const payload = {
      stars: 2,
      pizza_id: 1, // Pizza ID 1 already exists in the database.
    };

    const res = http.post(URL, JSON.stringify(payload), requestConfigWithTag({ name: &amp;#39;Create&amp;#39; }));

    if (check(res, { &amp;#39;Rating created correctly&amp;#39;: (r) =&amp;gt; r.status === 201 })) {
      URL = `${URL}/${res.json(&amp;#39;id&amp;#39;)}`;
    } else {
      console.log(`Unable to create rating ${res.status} ${res.body}`);
      return;
    }
  });

  group(&amp;#39;02. Fetch my ratings&amp;#39;, () =&amp;gt; {
    const res = http.get(`${BASE_URL}/api/ratings`, requestConfigWithTag({ name: &amp;#39;Fetch&amp;#39; }));
    check(res, { &amp;#39;retrieve ratings status&amp;#39;: (r) =&amp;gt; r.status === 200 });
    check(res.json(), { &amp;#39;retrieved ratings list&amp;#39;: (r) =&amp;gt; r.ratings.length &amp;gt; 0 });
  });

  group(&amp;#39;03. Update the rating&amp;#39;, () =&amp;gt; {
    const payload = { stars: 5 };
    const res = http.put(URL, JSON.stringify(payload), requestConfigWithTag({ name: &amp;#39;Update&amp;#39; }));
    const isSuccessfulUpdate = check(res, {
      &amp;#39;Update worked&amp;#39;: () =&amp;gt; res.status === 200,
      &amp;#39;Updated stars number is correct&amp;#39;: () =&amp;gt; res.json(&amp;#39;stars&amp;#39;) === 5,
    });

    if (!isSuccessfulUpdate) {
      console.log(`Unable to update the rating ${res.status} ${res.body}`);
      return;
    }
  });

  group(&amp;#39;04. Delete the rating&amp;#39;, () =&amp;gt; {
    const delRes = http.del(URL, null, requestConfigWithTag({ name: &amp;#39;Delete&amp;#39; }));

    const isSuccessfulDelete = check(null, {
      &amp;#39;Rating was deleted correctly&amp;#39;: () =&amp;gt; delRes.status === 204,
    });

    if (!isSuccessfulDelete) {
      console.log(&amp;#39;Rating was not deleted properly&amp;#39;);
      return;
    }
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;httpx-and-k6chaijs-example&#34;&gt;httpx and k6chaijs example&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { describe, expect } from &amp;#39;https://jslib.k6.io/k6chaijs/4.3.4.3/index.js&amp;#39;;
import { Httpx } from &amp;#39;https://jslib.k6.io/httpx/0.1.0/index.js&amp;#39;;
import {
  randomIntBetween,
  randomItem,
  randomString,
} from &amp;#39;https://jslib.k6.io/k6-utils/1.2.0/index.js&amp;#39;;

export const options = {
  // for the example, let&amp;#39;s run only 1 VU with 1 iteration
  vus: 1,
  iterations: 1,
};

const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`; // Set your own email;
const PASSWORD = &amp;#39;secret&amp;#39;;

const session = new Httpx({ baseURL: &amp;#39;https://quickpizza.grafana.com&amp;#39; });

// Register a new user and retrieve authentication token for subsequent API requests
export function setup() {
  let authToken = null;

  describe(`setup - create a test user ${USERNAME}`, () =&amp;gt; {
    const resp = session.post(
      `/api/users`,
      JSON.stringify({
        username: USERNAME,
        password: PASSWORD,
      })
    );

    expect(resp.status, &amp;#39;User create status&amp;#39;).to.equal(201);
    expect(resp, &amp;#39;User create valid json response&amp;#39;).to.have.validJsonBody();
  });

  describe(`setup - Authenticate the new user ${USERNAME}`, () =&amp;gt; {
    const resp = session.post(
      `/api/users/token/login`,
      JSON.stringify({
        username: USERNAME,
        password: PASSWORD,
      })
    );

    expect(resp.status, &amp;#39;Authenticate status&amp;#39;).to.equal(200);
    expect(resp, &amp;#39;Authenticate valid json response&amp;#39;).to.have.validJsonBody();
    authToken = resp.json(&amp;#39;token&amp;#39;);
    expect(authToken, &amp;#39;Authentication token&amp;#39;).to.be.a(&amp;#39;string&amp;#39;);
  });

  return authToken;
}

export default function (authToken) {
  // set the authorization header on the session for the subsequent requests
  session.addHeader(&amp;#39;Authorization&amp;#39;, `Bearer ${authToken}`);

  describe(&amp;#39;01. Create a new rating&amp;#39;, (t) =&amp;gt; {
    const payload = {
      stars: 2,
      pizza_id: 1, // Pizza ID 1 already exists in the database
    };

    session.addTag(&amp;#39;name&amp;#39;, &amp;#39;Create&amp;#39;);
    const resp = session.post(`/api/ratings`, JSON.stringify(payload));

    expect(resp.status, &amp;#39;Rating creation status&amp;#39;).to.equal(201);
    expect(resp, &amp;#39;Rating creation valid json response&amp;#39;).to.have.validJsonBody();

    session.newRatingId = resp.json(&amp;#39;id&amp;#39;);
  });

  describe(&amp;#39;02. Fetch my ratings&amp;#39;, (t) =&amp;gt; {
    session.clearTag(&amp;#39;name&amp;#39;);
    const resp = session.get(&amp;#39;/api/ratings&amp;#39;);

    expect(resp.status, &amp;#39;Fetch ratings status&amp;#39;).to.equal(200);
    expect(resp, &amp;#39;Fetch ratings valid json response&amp;#39;).to.have.validJsonBody();
    expect(resp.json(&amp;#39;ratings&amp;#39;).length, &amp;#39;Number of ratings&amp;#39;).to.be.above(0);
  });

  describe(&amp;#39;03. Update the rating&amp;#39;, (t) =&amp;gt; {
    const payload = {
      stars: 5,
    };

    const resp = session.patch(`/api/ratings/${session.newRatingId}`, JSON.stringify(payload));

    expect(resp.status, &amp;#39;Rating patch status&amp;#39;).to.equal(200);
    expect(resp, &amp;#39;Fetch rating valid json response&amp;#39;).to.have.validJsonBody();
    expect(resp.json(&amp;#39;stars&amp;#39;), &amp;#39;Stars&amp;#39;).to.equal(payload.stars);

    // read rating again to verify the update worked
    const resp1 = session.get(`/api/ratings/${session.newRatingId}`);

    expect(resp1.status, &amp;#39;Fetch rating status&amp;#39;).to.equal(200);
    expect(resp1, &amp;#39;Fetch rating valid json response&amp;#39;).to.have.validJsonBody();
    expect(resp1.json(&amp;#39;stars&amp;#39;), &amp;#39;Stars&amp;#39;).to.equal(payload.stars);
  });

  describe(&amp;#39;04. Delete the rating&amp;#39;, (t) =&amp;gt; {
    const resp = session.delete(`/api/ratings/${session.newRatingId}`);

    expect(resp.status, &amp;#39;Rating delete status&amp;#39;).to.equal(204);
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="api-crud-operations">API CRUD Operations&lt;/h1>
&lt;p>The examples showcase the testing of CRUD operations on a REST API.&lt;/p>
&lt;p>CRUD refers to the basic operations in a database: Create, Read, Update, and Delete. We can map these operations to HTTP methods in REST APIs:&lt;/p></description></item><item><title>Generating UUIDs</title><link>https://grafana.com/docs/k6/v2.3.x/examples/generating-uuids/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/generating-uuids/</guid><content><![CDATA[&lt;h1 id=&#34;generating-uuids&#34;&gt;Generating UUIDs&lt;/h1&gt;
&lt;p&gt;If you want to make a version 4 UUID,
you can use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/uuidv4/&#34;&gt;&lt;code&gt;uuidv4&lt;/code&gt; function&lt;/a&gt; from the &lt;a href=&#34;https://jslib.k6.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;k6 JS lib repository&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { uuidv4 } from &amp;#39;https://jslib.k6.io/k6-utils/1.4.0/index.js&amp;#39;;

export default function () {
  const randomUUID = uuidv4();
  console.log(randomUUID); // 35acae14-f7cb-468a-9866-1fc45713149a
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you really need other UUID versions, you must rely on an external library.&lt;/p&gt;
&lt;h2 id=&#34;generate-v1-uuids&#34;&gt;Generate v1 UUIDs&lt;/h2&gt;
&lt;p&gt;As k6 doesn&amp;rsquo;t have built-in support
for version 1 UUID, you&amp;rsquo;ll have to use a third-party library.&lt;/p&gt;
&lt;p&gt;This example uses a Node.js library called &lt;a href=&#34;https://www.npmjs.com/package/uuid&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;uuid&lt;/a&gt;
and &lt;a href=&#34;http://browserify.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Browserify&lt;/a&gt; (to make it work in k6).
For this to work, we first need to go through a few required steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Make sure you have the necessary prerequisites installed:
&lt;a href=&#34;https://nodejs.org/en/download/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Node.js&lt;/a&gt; and &lt;a href=&#34;http://browserify.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Browserify&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the &lt;code&gt;uuid&lt;/code&gt; library:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;npm install uuid@3.4.0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run it through browserify:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;browserify node_modules/uuid/index.js -s uuid &amp;gt; uuid.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Move the &lt;code&gt;uuid.js&lt;/code&gt; file to the same folder as your script file. Now you can import
it into your test script:&lt;/p&gt;
&lt;!-- md-k6:skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import uuid from &amp;#39;./uuid.js&amp;#39;;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This example generates a v1 UUID:&lt;/p&gt;
&lt;!-- md-k6:skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import uuid from &amp;#39;./uuid.js&amp;#39;;

export default function () {
  // Generate a UUID v1
  const uuid1 = uuid.v1();
  console.log(uuid1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="generating-uuids">Generating UUIDs&lt;/h1>
&lt;p>If you want to make a version 4 UUID,
you can use the
&lt;a href="/docs/k6/v2.3.x/javascript-api/jslib/utils/uuidv4/">&lt;code>uuidv4&lt;/code> function&lt;/a> from the &lt;a href="https://jslib.k6.io/" target="_blank" rel="noopener noreferrer">k6 JS lib repository&lt;/a>.&lt;/p>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { uuidv4 } from &amp;#39;https://jslib.k6.io/k6-utils/1.4.0/index.js&amp;#39;;
export default function () {
const randomUUID = uuidv4();
console.log(randomUUID); // 35acae14-f7cb-468a-9866-1fc45713149a
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;p>If you really need other UUID versions, you must rely on an external library.&lt;/p></description></item><item><title>HTTP2</title><link>https://grafana.com/docs/k6/v2.3.x/examples/http2/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/http2/</guid><content><![CDATA[&lt;h1 id=&#34;http2&#34;&gt;HTTP2&lt;/h1&gt;
&lt;p&gt;If the target system indicates that a connection can be upgraded from HTTP/1.1 to HTTP/2, k6 will do so automatically.&lt;/p&gt;
&lt;h2 id=&#34;making-http2-requests&#34;&gt;Making HTTP/2 requests&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

export default function () {
  const res = http.get(&amp;#39;https://quickpizza.grafana.com&amp;#39;);
  check(res, {
    &amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#39;protocol is HTTP/2&amp;#39;: (r) =&amp;gt; r.proto === &amp;#39;HTTP/2.0&amp;#39;,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="http2">HTTP2&lt;/h1>
&lt;p>If the target system indicates that a connection can be upgraded from HTTP/1.1 to HTTP/2, k6 will do so automatically.&lt;/p>
&lt;h2 id="making-http2-requests">Making HTTP/2 requests&lt;/h2>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;
export default function () {
const res = http.get(&amp;#39;https://quickpizza.grafana.com&amp;#39;);
check(res, {
&amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
&amp;#39;protocol is HTTP/2&amp;#39;: (r) =&amp;gt; r.proto === &amp;#39;HTTP/2.0&amp;#39;,
});
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div></description></item><item><title>Use global variables in k6</title><link>https://grafana.com/docs/k6/v2.3.x/examples/use-global-variables/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/use-global-variables/</guid><content><![CDATA[&lt;h1 id=&#34;use-global-variables-in-k6&#34;&gt;Use global variables in k6&lt;/h1&gt;
&lt;p&gt;A global variable is a variable that can be accessed from any scope. In the context of k6, global variables can be used to persist and pass information across iterations of a test run, and must be declared in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/test-lifecycle/#the-init-stage&#34;&gt;&lt;code&gt;init&lt;/code&gt; stage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A common use case is when you need to extract a value from a page, such as a CSRF or an API token, and reuse that across iterations of your test.&lt;/p&gt;
&lt;p&gt;There are multiple ways to use global variables in JavaScript, each with benefits and drawbacks.&lt;/p&gt;
&lt;p&gt;Before going into the examples, it&amp;rsquo;s important to note a caveat with how the k6 test lifecycle works, and how that can affect the usage of global variables.&lt;/p&gt;
&lt;h2 id=&#34;vu-isolation-and-global-variables&#34;&gt;VU isolation and global variables&lt;/h2&gt;
&lt;p&gt;In k6, variables defined in the &lt;code&gt;init&lt;/code&gt; context are copied to each Virtual User (VU) when the test starts. Each VU runs in complete isolation from the others, so any changes made to global variables during the test are local to the VU making them.&lt;/p&gt;
&lt;p&gt;This means that if you have, for example, 2 VUs and 4 iterations, and you increment a property on a global variable in each iteration, you might expect the final value to be 8. However, in reality, each VU will have its own copy, and the value will be 4 for each VU.&lt;/p&gt;
&lt;p&gt;For &lt;em&gt;read-only use-cases&lt;/em&gt; where you only use static values or set them once at the beginning, for example, in the &lt;code&gt;setup()&lt;/code&gt; function, this is not a problem. But if you modify global variables during the test, remember that each VU has its own instance, and changes are not shared between VUs.&lt;/p&gt;
&lt;p&gt;Refer to 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/test-lifecycle/&#34;&gt;Test lifecycle&lt;/a&gt; for more details about the test lifecycle stages.&lt;/p&gt;
&lt;h2 id=&#34;option-1-use-import-and-export&#34;&gt;Option 1: use &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The first option is to declare a global variables object in your main script and export it.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;import { doSomething, doSomethingElse } from &amp;#39;./imported-script.js&amp;#39;;

export const VARS = {};

export default function () {
  VARS.prop = &amp;#39;prop1&amp;#39;;

  doSomething();

  doSomethingElse();
  console.log(JSON.stringify(VARS));
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can then import the variable in your script, and use it across functions or alter the values:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;import { VARS } from &amp;#39;./main.js&amp;#39;;

export function doSomething() {
  console.log(JSON.stringify(VARS));
}

export function doSomethingElse() {
  VARS.prop2 = &amp;#39;prop2&amp;#39;;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The advantage of using this method is the fact that you need to explicitly use the &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt; statements. That can make it easier when working in a team, so other developers can understand your script logic and see where the variables and values came from.&lt;/p&gt;
&lt;h2 id=&#34;option-2-use-globalthis&#34;&gt;Option 2: use &lt;code&gt;globalThis&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The second option is to use the &lt;code&gt;globalThis&lt;/code&gt; JavaScript object, which is available in any JavaScript environment, not just k6.&lt;/p&gt;
&lt;p&gt;For example, in your main script you can add a property to &lt;code&gt;globalThis&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;import { doSomething, doSomethingElse } from &amp;#39;./imported-script.js&amp;#39;;

globalThis.VARS = {};

export default function () {
  globalThis.VARS.prop = &amp;#39;prop1&amp;#39;;

  doSomething();

  doSomethingElse();
  console.log(JSON.stringify(globalThis.VARS));
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And, similarly to the previous option, you can use access it from anywhere in that script or in imported scripts as well:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;js&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-js&#34;&gt;export function doSomething() {
  console.log(JSON.stringify(globalThis.VARS));
}

export function doSomethingElse() {
  globalThis.VARS.prop2 = &amp;#39;prop2&amp;#39;;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The advantage to using the &lt;code&gt;globalThis&lt;/code&gt; object is that you don&amp;rsquo;t need to &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;export&lt;/code&gt; a global variable. The downside is that, depending on how complex or extensive your test scripts are, using the &lt;code&gt;globalThis&lt;/code&gt; variable can make your script more verbose, and cause unintended behavior if you&amp;rsquo;re not careful about how you&amp;rsquo;re using and setting global variables.&lt;/p&gt;
]]></content><description>&lt;h1 id="use-global-variables-in-k6">Use global variables in k6&lt;/h1>
&lt;p>A global variable is a variable that can be accessed from any scope. In the context of k6, global variables can be used to persist and pass information across iterations of a test run, and must be declared in the
&lt;a href="/docs/k6/v2.3.x/using-k6/test-lifecycle/#the-init-stage">&lt;code>init&lt;/code> stage&lt;/a>.&lt;/p></description></item><item><title>WebSockets</title><link>https://grafana.com/docs/k6/v2.3.x/examples/websockets/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/websockets/</guid><content><![CDATA[&lt;h1 id=&#34;websockets&#34;&gt;WebSockets&lt;/h1&gt;
&lt;p&gt;Here&amp;rsquo;s a load test for the QuickPizza WebSocket API, available on &lt;a href=&#34;https://quickpizza.grafana.com/ws&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://quickpizza.grafana.com/ws&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Multiple VUs connect using a VU-indexed user name, and send random messages.&lt;/p&gt;
&lt;p&gt;Each VU receives messages sent by all other VUs.&lt;/p&gt;
&lt;!-- md-k6:fixedscenarios --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { randomString, randomIntBetween } from &amp;#39;https://jslib.k6.io/k6-utils/1.2.0/index.js&amp;#39;;
import ws from &amp;#39;k6/ws&amp;#39;;
import { check, sleep } from &amp;#39;k6&amp;#39;;

const sessionDuration = randomIntBetween(3000, 6000); // user session between 3s and 6s

export const options = {
  vus: 10,
  iterations: 10,
};

export default function () {
  const url = `wss://quickpizza.grafana.com/ws`;
  const params = { tags: { my_tag: &amp;#39;my ws session&amp;#39; } };
  const user = `user_${__VU}`;

  const res = ws.connect(url, params, function (socket) {
    socket.on(&amp;#39;open&amp;#39;, function open() {
      console.log(`VU ${__VU}: connected`);

      socket.send(JSON.stringify({ msg: &amp;#39;Hello!&amp;#39;, user: user }));

      socket.setInterval(function timeout() {
        socket.send(
          JSON.stringify({
            user: user,
            msg: `I&amp;#39;m saying ${randomString(5)}`,
            foo: &amp;#39;bar&amp;#39;,
          })
        );
      }, randomIntBetween(1000, 2000)); // say something every 1-2 seconds
    });

    socket.on(&amp;#39;ping&amp;#39;, function () {
      console.log(&amp;#39;PING!&amp;#39;);
    });

    socket.on(&amp;#39;pong&amp;#39;, function () {
      console.log(&amp;#39;PONG!&amp;#39;);
    });

    socket.on(&amp;#39;close&amp;#39;, function () {
      console.log(`VU ${__VU}: disconnected`);
    });

    socket.on(&amp;#39;message&amp;#39;, function (message) {
      const data = JSON.parse(message);
      console.log(`VU ${__VU} received message: ${data.msg}`);
    });

    socket.setTimeout(function () {
      console.log(`VU ${__VU}: ${sessionDuration}ms passed, leaving the website`);
      socket.send(JSON.stringify({ msg: &amp;#39;Goodbye!&amp;#39;, user: user }));
    }, sessionDuration);

    socket.setTimeout(function () {
      console.log(`Closing the socket forcefully 3s after graceful LEAVE`);
      socket.close();
    }, sessionDuration &amp;#43; 3000);
  });

  check(res, { &amp;#39;Connected successfully&amp;#39;: (r) =&amp;gt; r &amp;amp;&amp;amp; r.status === 101 });
  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="websockets">WebSockets&lt;/h1>
&lt;p>Here&amp;rsquo;s a load test for the QuickPizza WebSocket API, available on &lt;a href="https://quickpizza.grafana.com/ws" target="_blank" rel="noopener noreferrer">https://quickpizza.grafana.com/ws&lt;/a>.&lt;/p>
&lt;p>Multiple VUs connect using a VU-indexed user name, and send random messages.&lt;/p></description></item><item><title>SOAP</title><link>https://grafana.com/docs/k6/v2.3.x/examples/soap/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/soap/</guid><content><![CDATA[&lt;h1 id=&#34;soap&#34;&gt;SOAP&lt;/h1&gt;
&lt;p&gt;Although k6 doesn&amp;rsquo;t have any built-in APIs for working with SOAP or XML data in general, you
can still easily load test a SOAP-based API by crafting SOAP messages and using the HTTP request APIs.&lt;/p&gt;
&lt;h2 id=&#34;making-soap-requests&#34;&gt;Making SOAP requests&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check, sleep } from &amp;#39;k6&amp;#39;;

const soapReqBody = `
&amp;lt;soapenv:Envelope xmlns:soapenv=&amp;#34;http://schemas.xmlsoap.org/soap/envelope/&amp;#34; xmlns:hs=&amp;#34;http://www.holidaywebservice.com/HolidayService_v2/&amp;#34;&amp;gt;
    &amp;lt;soapenv:Body&amp;gt;
        &amp;lt;hs:GetHolidaysAvailable&amp;gt;
            &amp;lt;hs:countryCode&amp;gt;UnitedStates&amp;lt;/hs:countryCode&amp;gt;
        &amp;lt;/hs:GetHolidaysAvailable&amp;gt;
    &amp;lt;/soapenv:Body&amp;gt;
&amp;lt;/soapenv:Envelope&amp;gt;`;

export default function () {
  // When making a SOAP POST request we must not forget to set the content type to text/xml
  const res = http.post(
    &amp;#39;http://www.holidaywebservice.com/HolidayService_v2/HolidayService2.asmx&amp;#39;,
    soapReqBody,
    {
      headers: { &amp;#39;Content-Type&amp;#39;: &amp;#39;text/xml&amp;#39; },
    }
  );

  // Make sure the response is correct
  check(res, {
    &amp;#39;status is 200&amp;#39;: (r) =&amp;gt; r.status === 200,
    &amp;#39;black friday is present&amp;#39;: (r) =&amp;gt; r.body.indexOf(&amp;#39;BLACK-FRIDAY&amp;#39;) !== -1,
  });

  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="soap">SOAP&lt;/h1>
&lt;p>Although k6 doesn&amp;rsquo;t have any built-in APIs for working with SOAP or XML data in general, you
can still easily load test a SOAP-based API by crafting SOAP messages and using the HTTP request APIs.&lt;/p></description></item><item><title>Transport Layer Security (TLS)</title><link>https://grafana.com/docs/k6/v2.3.x/examples/tls/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/tls/</guid><content><![CDATA[&lt;h1 id=&#34;transport-layer-security-tls&#34;&gt;Transport Layer Security (TLS)&lt;/h1&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

export const options = {
  tlsCipherSuites: [&amp;#39;TLS_RSA_WITH_RC4_128_SHA&amp;#39;, &amp;#39;TLS_RSA_WITH_AES_128_GCM_SHA256&amp;#39;],
  tlsVersion: {
    min: &amp;#39;ssl3.0&amp;#39;,
    max: &amp;#39;tls1.2&amp;#39;,
  },
};

export default function () {
  const res = http.get(&amp;#39;https://sha256.badssl.com&amp;#39;);
  check(res, {
    &amp;#39;is TLSv1.2&amp;#39;: (r) =&amp;gt; r.tls_version === http.TLS_1_2,
    &amp;#39;is sha256 cipher suite&amp;#39;: (r) =&amp;gt; r.tls_cipher_suite === &amp;#39;TLS_RSA_WITH_AES_128_GCM_SHA256&amp;#39;,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="transport-layer-security-tls">Transport Layer Security (TLS)&lt;/h1>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;
export const options = {
tlsCipherSuites: [&amp;#39;TLS_RSA_WITH_RC4_128_SHA&amp;#39;, &amp;#39;TLS_RSA_WITH_AES_128_GCM_SHA256&amp;#39;],
tlsVersion: {
min: &amp;#39;ssl3.0&amp;#39;,
max: &amp;#39;tls1.2&amp;#39;,
},
};
export default function () {
const res = http.get(&amp;#39;https://sha256.badssl.com&amp;#39;);
check(res, {
&amp;#39;is TLSv1.2&amp;#39;: (r) =&amp;gt; r.tls_version === http.TLS_1_2,
&amp;#39;is sha256 cipher suite&amp;#39;: (r) =&amp;gt; r.tls_cipher_suite === &amp;#39;TLS_RSA_WITH_AES_128_GCM_SHA256&amp;#39;,
});
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div></description></item><item><title>Generating realistic data</title><link>https://grafana.com/docs/k6/v2.3.x/examples/data-generation/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/data-generation/</guid><content><![CDATA[&lt;h1 id=&#34;generating-realistic-data&#34;&gt;Generating realistic data&lt;/h1&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;https://github.com/grafana/k6-example-data-generation&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;grafana/k6-example-data-generation&lt;/a&gt; GitHub repository for an example of how to utilize k6 and Faker to generate realistic data for a load test.&lt;/p&gt;
]]></content><description>&lt;h1 id="generating-realistic-data">Generating realistic data&lt;/h1>
&lt;p>Refer to the &lt;a href="https://github.com/grafana/k6-example-data-generation" target="_blank" rel="noopener noreferrer">grafana/k6-example-data-generation&lt;/a> GitHub repository for an example of how to utilize k6 and Faker to generate realistic data for a load test.&lt;/p></description></item><item><title>Bundling and transpiling</title><link>https://grafana.com/docs/k6/v2.3.x/examples/bundling-and-transpiling/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/bundling-and-transpiling/</guid><content><![CDATA[&lt;h1 id=&#34;bundling-and-transpiling&#34;&gt;Bundling and transpiling&lt;/h1&gt;
&lt;p&gt;For more details about bundling and transpiling, refer to 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/javascript-typescript-compatibility-mode/&#34;&gt;JavaScript and TypeScript compatibility mode&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h1 id="bundling-and-transpiling">Bundling and transpiling&lt;/h1>
&lt;p>For more details about bundling and transpiling, refer to
&lt;a href="/docs/k6/v2.3.x/using-k6/javascript-typescript-compatibility-mode/">JavaScript and TypeScript compatibility mode&lt;/a>.&lt;/p></description></item><item><title>Functional testing</title><link>https://grafana.com/docs/k6/v2.3.x/examples/functional-testing/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/functional-testing/</guid><content><![CDATA[&lt;h1 id=&#34;functional-testing&#34;&gt;Functional testing&lt;/h1&gt;
&lt;h3 id=&#34;most-basic-integration-test&#34;&gt;Most basic integration test&lt;/h3&gt;
&lt;!-- eslint-skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { describe, expect } from &amp;#39;https://jslib.k6.io/k6chaijs/4.3.4.3/index.js&amp;#39;;

export const options = {
  thresholds: {
    checks: [&amp;#39;rate == 1.00&amp;#39;],
  },
};

export default function () {
  describe(&amp;#39;Hello world!&amp;#39;, () =&amp;gt; {
    const response = http.get(&amp;#39;https://quickpizza.grafana.com/api/ratings&amp;#39;, {
      headers: { Authorization: &amp;#39;Token abcdef0123456789&amp;#39; },
    });

    expect(response.status, &amp;#39;response status&amp;#39;).to.equal(200);
    expect(response).to.have.validJsonBody();
    expect(response.json(&amp;#39;ratings&amp;#39;), &amp;#39;ratings list&amp;#39;).to.be.an(&amp;#39;array&amp;#39;);
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;sample-integration-test&#34;&gt;Sample integration test&lt;/h3&gt;
&lt;p&gt;This test goes through several steps. It creates a new user account, authenticates, and interacts with protected resources.&lt;/p&gt;
&lt;!-- md-k6:skip --&gt;
&lt;!-- eslint-skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import chai, { describe, expect } from &amp;#39;https://jslib.k6.io/k6chaijs/4.3.4.3/index.js&amp;#39;;
import { Httpx, Get } from &amp;#39;https://jslib.k6.io/httpx/0.0.6/index.js&amp;#39;;
import { randomString } from &amp;#39;https://jslib.k6.io/k6-utils/1.0.0/index.js&amp;#39;;

chai.config.logFailures = true;

export let options = {
  thresholds: {
    // fail the test if any checks fail or any requests fail
    checks: [&amp;#39;rate == 1.00&amp;#39;],
    http_req_failed: [&amp;#39;rate == 0.00&amp;#39;],
  },
  vus: 1,
  iterations: 1,
};

let session = new Httpx({
  baseURL: &amp;#39;https://quickpizza.grafana.com&amp;#39;,
  headers: { Authorization: &amp;#39;Token abcdef0123456789&amp;#39; },
});

function retrieveIndividualRatingsInABatch() {
  describe(&amp;#39;[Ratings service] Fetch public ratings one by one&amp;#39;, () =&amp;gt; {
    let responses = session.batch([
      new Get(&amp;#39;/api/ratings/1&amp;#39;),
      new Get(&amp;#39;/api/ratings/2&amp;#39;),
      new Get(&amp;#39;/api/ratings/3&amp;#39;),
    ]);

    expect(responses, &amp;#39;responses&amp;#39;).to.be.an(&amp;#39;array&amp;#39;);

    responses.forEach((response) =&amp;gt; {
      expect(response.status, &amp;#39;response status&amp;#39;).to.equal(200);
      expect(response).to.have.validJsonBody();
      expect(response.json(), &amp;#39;rating&amp;#39;).to.be.an(&amp;#39;object&amp;#39;);
      expect(response.json(), &amp;#39;rating&amp;#39;).to.include.keys(&amp;#39;id&amp;#39;, &amp;#39;stars&amp;#39;, &amp;#39;pizza_id&amp;#39;);
      expect(response.json(), &amp;#39;rating&amp;#39;).to.not.have.a.property(&amp;#39;language&amp;#39;);
    });
  });
}

function retrieveAllPublicRatings() {
  describe(&amp;#39;[Crocs service] Fetch a list of crocs&amp;#39;, () =&amp;gt; {
    let response = session.get(&amp;#39;/api/ratings&amp;#39;);

    expect(response.status, &amp;#39;response status&amp;#39;).to.equal(200);
    expect(response).to.have.validJsonBody();
    expect(response.json(&amp;#39;ratings&amp;#39;), &amp;#39;ratings list&amp;#39;).to.be.an(&amp;#39;array&amp;#39;).lengthOf.above(2);
  });
}

function validateAuthService() {
  const USERNAME = `${randomString(10)}@example.com`;
  const PASSWORD = &amp;#39;superCroc2021&amp;#39;;

  describe(&amp;#39;[Registration service] user registration&amp;#39;, () =&amp;gt; {
    let sampleUser = {
      username: USERNAME,
      password: PASSWORD,
    };

    let response = session.post(`/api/users`, JSON.stringify(sampleUser));

    expect(response.status, &amp;#39;registration status&amp;#39;).to.equal(201);
    expect(response).to.have.validJsonBody();
  });

  describe(&amp;#39;[Auth service] user authentication&amp;#39;, () =&amp;gt; {
    let authData = {
      username: USERNAME,
      password: PASSWORD,
    };

    let resp = session.post(`/api/users/token/login`, JSON.stringify(authData));

    expect(resp.status, &amp;#39;Auth status&amp;#39;).to.be.within(200, 204);
    expect(resp).to.have.validJsonBody();
    expect(resp.json()).to.have.a.property(&amp;#39;token&amp;#39;);
    expect(resp.json(&amp;#39;token&amp;#39;), &amp;#39;auth token&amp;#39;).to.be.a(&amp;#39;string&amp;#39;);

    let authToken = resp.json(&amp;#39;token&amp;#39;);
    // set the authorization header on the session for the subsequent requests.
    session.addHeader(&amp;#39;Authorization&amp;#39;, `Token ${authToken}`);
  });
}

function validateRatingCreation() {
  // authentication happened before this call.

  describe(&amp;#39;[Ratings service] Create a new rating&amp;#39;, () =&amp;gt; {
    let payload = {
      stars: 2,
      pizza_id: 1,
    };

    let resp = session.post(`/api/ratings`, JSON.stringify(payload));

    expect(resp.status, &amp;#39;Rating creation status&amp;#39;).to.equal(201);
    expect(resp).to.have.validJsonBody();

    session.newRatingId = resp.json(&amp;#39;id&amp;#39;); // caching ID for the future
  });

  describe(&amp;#39;[Ratings service] Fetch private ratings&amp;#39;, () =&amp;gt; {
    let response = session.get(&amp;#39;/api/ratings&amp;#39;);

    expect(response.status, &amp;#39;response status&amp;#39;).to.equal(200);
    expect(response, &amp;#39;ratings&amp;#39;).to.have.validJsonBody();
    expect(response.json(&amp;#39;ratings&amp;#39;), &amp;#39;ratings&amp;#39;).to.not.be.empty;
  });
}

export default function testSuite() {
  retrieveIndividualRatingsInABatch();
  retrieveAllPublicRatings();
  validateAuthService();
  validateRatingCreation();
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;full-example-showcasing-all-functionality&#34;&gt;Full example showcasing all functionality&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s an auto-generated k6 test script showcasing all examples from the &lt;a href=&#34;https://www.chaijs.com/api/bdd/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Chaijs API documentation&lt;/a&gt;.&lt;/p&gt;
&lt;!-- md-k6:skip --&gt;
&lt;!-- eslint-skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import chai, { describe, expect } from &amp;#39;https://jslib.k6.io/k6chaijs/4.5.0.1/index.js&amp;#39;;

chai.config.aggregateChecks = false;
chai.config.logFailures = true;

export default function testSuite() {
  describe(&amp;#39;docs example 0&amp;#39;, () =&amp;gt; {
    expect(function () {}).to.not.throw();
    expect({ a: 1 }).to.not.have.property(&amp;#39;b&amp;#39;);
    expect([1, 2]).to.be.an(&amp;#39;array&amp;#39;).that.does.not.include(3);
  });

  describe(&amp;#39;docs example 1&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(2).to.not.equal(1); // Not recommended
  });

  describe(&amp;#39;docs example 2&amp;#39;, () =&amp;gt; {
    // Target object deeply (but not strictly) equals `{a: 1}`
    expect({ a: 1 }).to.deep.equal({ a: 1 });
    expect({ a: 1 }).to.not.equal({ a: 1 });

    // Target array deeply (but not strictly) includes `{a: 1}`
    expect([{ a: 1 }]).to.deep.include({ a: 1 });
    expect([{ a: 1 }]).to.not.include({ a: 1 });

    // Target object deeply (but not strictly) includes `x: {a: 1}`
    expect({ x: { a: 1 } }).to.deep.include({ x: { a: 1 } });
    expect({ x: { a: 1 } }).to.not.include({ x: { a: 1 } });

    // Target array deeply (but not strictly) has member `{a: 1}`
    expect([{ a: 1 }]).to.have.deep.members([{ a: 1 }]);
    expect([{ a: 1 }]).to.not.have.members([{ a: 1 }]);

    // Target set deeply (but not strictly) has key `{a: 1}`
    expect(new Set([{ a: 1 }])).to.have.deep.keys([{ a: 1 }]);
    expect(new Set([{ a: 1 }])).to.not.have.keys([{ a: 1 }]);

    // Target object deeply (but not strictly) has property `x: {a: 1}`
    expect({ x: { a: 1 } }).to.have.deep.property(&amp;#39;x&amp;#39;, { a: 1 });
    expect({ x: { a: 1 } }).to.not.have.property(&amp;#39;x&amp;#39;, { a: 1 });
  });

  describe(&amp;#39;docs example 3&amp;#39;, () =&amp;gt; {
    expect({ a: { b: [&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;] } }).to.have.nested.property(&amp;#39;a.b[1]&amp;#39;);
    expect({ a: { b: [&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;] } }).to.nested.include({ &amp;#39;a.b[1]&amp;#39;: &amp;#39;y&amp;#39; });
  });

  describe(&amp;#39;docs example 4&amp;#39;, () =&amp;gt; {
    expect({ &amp;#39;.a&amp;#39;: { &amp;#39;[b]&amp;#39;: &amp;#39;x&amp;#39; } }).to.have.nested.property(&amp;#39;\\.a.\\[b\\]&amp;#39;);
    expect({ &amp;#39;.a&amp;#39;: { &amp;#39;[b]&amp;#39;: &amp;#39;x&amp;#39; } }).to.nested.include({ &amp;#39;\\.a.\\[b\\]&amp;#39;: &amp;#39;x&amp;#39; });
  });

  describe(&amp;#39;docs example 5&amp;#39;, () =&amp;gt; {
    Object.prototype.b = 2;

    expect({ a: 1 }).to.have.own.property(&amp;#39;a&amp;#39;);
    expect({ a: 1 }).to.have.property(&amp;#39;b&amp;#39;);
    expect({ a: 1 }).to.not.have.own.property(&amp;#39;b&amp;#39;);

    expect({ a: 1 }).to.own.include({ a: 1 });
    expect({ a: 1 }).to.include({ b: 2 }).but.not.own.include({ b: 2 });
  });

  describe(&amp;#39;docs example 6&amp;#39;, () =&amp;gt; {
    expect([1, 2]).to.have.ordered.members([1, 2]).but.not.have.ordered.members([2, 1]);
  });

  describe(&amp;#39;docs example 7&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.include.ordered.members([1, 2]).but.not.include.ordered.members([2, 3]);
  });

  describe(&amp;#39;docs example 8&amp;#39;, () =&amp;gt; {
    expect({ a: 1, b: 2 }).to.not.have.any.keys(&amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;);
  });

  describe(&amp;#39;docs example 9&amp;#39;, () =&amp;gt; {
    expect({ a: 1, b: 2 }).to.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 10&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.be.a(&amp;#39;string&amp;#39;);
    expect({ a: 1 }).to.be.an(&amp;#39;object&amp;#39;);
    expect(null).to.be.a(&amp;#39;null&amp;#39;);
    expect(undefined).to.be.an(&amp;#39;undefined&amp;#39;);
    expect(new Error()).to.be.an(&amp;#39;error&amp;#39;);
    expect(Promise.resolve()).to.be.a(&amp;#39;promise&amp;#39;);
    expect(new Float32Array()).to.be.a(&amp;#39;float32array&amp;#39;);
    expect(Symbol()).to.be.a(&amp;#39;symbol&amp;#39;);
  });

  describe(&amp;#39;docs example 11&amp;#39;, () =&amp;gt; {
    var myObj = {
      [Symbol.toStringTag]: &amp;#39;myCustomType&amp;#39;,
    };

    expect(myObj).to.be.a(&amp;#39;myCustomType&amp;#39;).but.not.an(&amp;#39;object&amp;#39;);
  });

  describe(&amp;#39;docs example 12&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.be.an(&amp;#39;array&amp;#39;).that.includes(2);
    expect([]).to.be.an(&amp;#39;array&amp;#39;).that.is.empty;
  });

  describe(&amp;#39;docs example 13&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.be.a(&amp;#39;string&amp;#39;); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.not.be.an(&amp;#39;array&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 14&amp;#39;, () =&amp;gt; {
    expect(1).to.be.a(&amp;#39;string&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.be.a(&amp;#39;string&amp;#39;);
  });

  describe(&amp;#39;docs example 15&amp;#39;, () =&amp;gt; {
    expect({ b: 2 }).to.have.a.property(&amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 16&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.include(&amp;#39;foo&amp;#39;);
  });

  describe(&amp;#39;docs example 17&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.include(2);
  });

  describe(&amp;#39;docs example 18&amp;#39;, () =&amp;gt; {
    expect({ a: 1, b: 2, c: 3 }).to.include({ a: 1, b: 2 });
  });

  describe(&amp;#39;docs example 19&amp;#39;, () =&amp;gt; {
    expect(new Set([1, 2])).to.include(2);
  });

  describe(&amp;#39;docs example 20&amp;#39;, () =&amp;gt; {
    expect(
      new Map([
        [&amp;#39;a&amp;#39;, 1],
        [&amp;#39;b&amp;#39;, 2],
      ])
    ).to.include(2);
  });

  describe(&amp;#39;docs example 21&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.be.an(&amp;#39;array&amp;#39;).that.includes(2);
  });

  describe(&amp;#39;docs example 22&amp;#39;, () =&amp;gt; {
    // Target array deeply (but not strictly) includes `{a: 1}`
    expect([{ a: 1 }]).to.deep.include({ a: 1 });
    expect([{ a: 1 }]).to.not.include({ a: 1 });

    // Target object deeply (but not strictly) includes `x: {a: 1}`
    expect({ x: { a: 1 } }).to.deep.include({ x: { a: 1 } });
    expect({ x: { a: 1 } }).to.not.include({ x: { a: 1 } });
  });

  describe(&amp;#39;docs example 23&amp;#39;, () =&amp;gt; {
    Object.prototype.b = 2;

    expect({ a: 1 }).to.own.include({ a: 1 });
    expect({ a: 1 }).to.include({ b: 2 }).but.not.own.include({ b: 2 });
  });

  describe(&amp;#39;docs example 24&amp;#39;, () =&amp;gt; {
    expect({ a: { b: 2 } }).to.deep.own.include({ a: { b: 2 } });
  });

  describe(&amp;#39;docs example 25&amp;#39;, () =&amp;gt; {
    expect({ a: { b: [&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;] } }).to.nested.include({ &amp;#39;a.b[1]&amp;#39;: &amp;#39;y&amp;#39; });
  });

  describe(&amp;#39;docs example 26&amp;#39;, () =&amp;gt; {
    expect({ &amp;#39;.a&amp;#39;: { &amp;#39;[b]&amp;#39;: 2 } }).to.nested.include({ &amp;#39;\\.a.\\[b\\]&amp;#39;: 2 });
  });

  describe(&amp;#39;docs example 27&amp;#39;, () =&amp;gt; {
    expect({ a: { b: [{ c: 3 }] } }).to.deep.nested.include({ &amp;#39;a.b[0]&amp;#39;: { c: 3 } });
  });

  describe(&amp;#39;docs example 28&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.not.include(&amp;#39;taco&amp;#39;);
    expect([1, 2, 3]).to.not.include(4);
  });

  describe(&amp;#39;docs example 29&amp;#39;, () =&amp;gt; {
    expect({ c: 3 }).to.not.have.any.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;); // Recommended
    expect({ c: 3 }).to.not.include({ a: 1, b: 2 }); // Not recommended
  });

  describe(&amp;#39;docs example 30&amp;#39;, () =&amp;gt; {
    expect({ a: 3, b: 4 }).to.include({ a: 3, b: 4 }); // Recommended
    expect({ a: 3, b: 4 }).to.not.include({ a: 1, b: 2 }); // Not recommended
  });

  describe(&amp;#39;docs example 31&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.include(4, &amp;#39;nooo why fail??&amp;#39;);
    expect([1, 2, 3], &amp;#39;nooo why fail??&amp;#39;).to.include(4);
  });

  describe(&amp;#39;docs example 32&amp;#39;, () =&amp;gt; {
    // Target object&amp;#39;s keys are a superset of [&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;] but not identical
    expect({ a: 1, b: 2, c: 3 }).to.include.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
    expect({ a: 1, b: 2, c: 3 }).to.not.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);

    // Target array is a superset of [1, 2] but not identical
    expect([1, 2, 3]).to.include.members([1, 2]);
    expect([1, 2, 3]).to.not.have.members([1, 2]);

    // Duplicates in the subset are ignored
    expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
  });

  describe(&amp;#39;docs example 33&amp;#39;, () =&amp;gt; {
    // Both assertions are identical
    expect({ a: 1 }).to.include.any.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
    expect({ a: 1 }).to.have.any.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 34&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.be.ok; // Not recommended

    expect(true).to.be.true; // Recommended
    expect(true).to.be.ok; // Not recommended
  });

  describe(&amp;#39;docs example 35&amp;#39;, () =&amp;gt; {
    expect(0).to.equal(0); // Recommended
    expect(0).to.not.be.ok; // Not recommended

    expect(false).to.be.false; // Recommended
    expect(false).to.not.be.ok; // Not recommended

    expect(null).to.be.null; // Recommended
    expect(null).to.not.be.ok; // Not recommended

    expect(undefined).to.be.undefined; // Recommended
    expect(undefined).to.not.be.ok; // Not recommended
  });

  describe(&amp;#39;docs example 36&amp;#39;, () =&amp;gt; {
    expect(false, &amp;#39;nooo why fail??&amp;#39;).to.be.ok;
  });

  describe(&amp;#39;docs example 37&amp;#39;, () =&amp;gt; {
    expect(true).to.be.true;
  });

  describe(&amp;#39;docs example 38&amp;#39;, () =&amp;gt; {
    expect(false).to.be.false; // Recommended
    expect(false).to.not.be.true; // Not recommended

    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.true; // Not recommended
  });

  describe(&amp;#39;docs example 39&amp;#39;, () =&amp;gt; {
    expect(false, &amp;#39;nooo why fail??&amp;#39;).to.be.true;
  });

  describe(&amp;#39;docs example 40&amp;#39;, () =&amp;gt; {
    expect(false).to.be.false;
  });

  describe(&amp;#39;docs example 41&amp;#39;, () =&amp;gt; {
    expect(true).to.be.true; // Recommended
    expect(true).to.not.be.false; // Not recommended

    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.false; // Not recommended
  });

  describe(&amp;#39;docs example 42&amp;#39;, () =&amp;gt; {
    expect(true, &amp;#39;nooo why fail??&amp;#39;).to.be.false;
  });

  describe(&amp;#39;docs example 43&amp;#39;, () =&amp;gt; {
    expect(null).to.be.null;
  });

  describe(&amp;#39;docs example 44&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.null; // Not recommended
  });

  describe(&amp;#39;docs example 45&amp;#39;, () =&amp;gt; {
    expect(42, &amp;#39;nooo why fail??&amp;#39;).to.be.null;
  });

  describe(&amp;#39;docs example 46&amp;#39;, () =&amp;gt; {
    expect(undefined).to.be.undefined;
  });

  describe(&amp;#39;docs example 47&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.undefined; // Not recommended
  });

  describe(&amp;#39;docs example 48&amp;#39;, () =&amp;gt; {
    expect(42, &amp;#39;nooo why fail??&amp;#39;).to.be.undefined;
  });

  describe(&amp;#39;docs example 49&amp;#39;, () =&amp;gt; {
    expect(NaN).to.be.NaN;
  });

  describe(&amp;#39;docs example 50&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.equal(&amp;#39;foo&amp;#39;); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.not.be.NaN; // Not recommended
  });

  describe(&amp;#39;docs example 51&amp;#39;, () =&amp;gt; {
    expect(42, &amp;#39;nooo why fail??&amp;#39;).to.be.NaN;
  });

  describe(&amp;#39;docs example 52&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.exist; // Not recommended

    expect(0).to.equal(0); // Recommended
    expect(0).to.exist; // Not recommended
  });

  describe(&amp;#39;docs example 53&amp;#39;, () =&amp;gt; {
    expect(null).to.be.null; // Recommended
    expect(null).to.not.exist; // Not recommended

    expect(undefined).to.be.undefined; // Recommended
    expect(undefined).to.not.exist; // Not recommended
  });

  describe(&amp;#39;docs example 54&amp;#39;, () =&amp;gt; {
    expect(null, &amp;#39;nooo why fail??&amp;#39;).to.exist;
  });

  describe(&amp;#39;docs example 55&amp;#39;, () =&amp;gt; {
    expect([]).to.be.empty;
    expect(&amp;#39;&amp;#39;).to.be.empty;
  });

  describe(&amp;#39;docs example 56&amp;#39;, () =&amp;gt; {
    expect(new Set()).to.be.empty;
    expect(new Map()).to.be.empty;
  });

  describe(&amp;#39;docs example 57&amp;#39;, () =&amp;gt; {
    expect({}).to.be.empty;
  });

  describe(&amp;#39;docs example 58&amp;#39;, () =&amp;gt; {
    expect([]).to.be.an(&amp;#39;array&amp;#39;).that.is.empty;
  });

  describe(&amp;#39;docs example 59&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
    expect([1, 2, 3]).to.not.be.empty; // Not recommended

    expect(new Set([1, 2, 3])).to.have.property(&amp;#39;size&amp;#39;, 3); // Recommended
    expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended

    expect(Object.keys({ a: 1 })).to.have.lengthOf(1); // Recommended
    expect({ a: 1 }).to.not.be.empty; // Not recommended
  });

  describe(&amp;#39;docs example 60&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3], &amp;#39;nooo why fail??&amp;#39;).to.be.empty;
  });

  describe(&amp;#39;docs example 61&amp;#39;, () =&amp;gt; {
    function test() {
      expect(arguments).to.be.arguments;
    }

    test();
  });

  describe(&amp;#39;docs example 62&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.be.a(&amp;#39;string&amp;#39;); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.not.be.arguments; // Not recommended
  });

  describe(&amp;#39;docs example 63&amp;#39;, () =&amp;gt; {
    expect({}, &amp;#39;nooo why fail??&amp;#39;).to.be.arguments;
  });

  describe(&amp;#39;docs example 64&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1);
    expect(&amp;#39;foo&amp;#39;).to.equal(&amp;#39;foo&amp;#39;);
  });

  describe(&amp;#39;docs example 65&amp;#39;, () =&amp;gt; {
    // Target object deeply (but not strictly) equals `{a: 1}`
    expect({ a: 1 }).to.deep.equal({ a: 1 });
    expect({ a: 1 }).to.not.equal({ a: 1 });

    // Target array deeply (but not strictly) equals `[1, 2]`
    expect([1, 2]).to.deep.equal([1, 2]);
    expect([1, 2]).to.not.equal([1, 2]);
  });

  describe(&amp;#39;docs example 66&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.not.equal(2); // Not recommended
  });

  describe(&amp;#39;docs example 67&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(2, &amp;#39;nooo why fail??&amp;#39;);
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.equal(2);
  });

  describe(&amp;#39;docs example 68&amp;#39;, () =&amp;gt; {
    // Target object is deeply (but not strictly) equal to {a: 1}
    expect({ a: 1 }).to.eql({ a: 1 }).but.not.equal({ a: 1 });

    // Target array is deeply (but not strictly) equal to [1, 2]
    expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
  });

  describe(&amp;#39;docs example 69&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.eql({ a: 1 }); // Recommended
    expect({ a: 1 }).to.not.eql({ b: 2 }); // Not recommended
  });

  describe(&amp;#39;docs example 70&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.eql({ b: 2 }, &amp;#39;nooo why fail??&amp;#39;);
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.eql({ b: 2 });
  });

  describe(&amp;#39;docs example 71&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(2).to.be.above(1); // Not recommended
  });

  describe(&amp;#39;docs example 72&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf(3); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf.above(2); // Not recommended

    expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
    expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended
  });

  describe(&amp;#39;docs example 73&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(1).to.not.be.above(2); // Not recommended
  });

  describe(&amp;#39;docs example 74&amp;#39;, () =&amp;gt; {
    expect(1).to.be.above(2, &amp;#39;nooo why fail??&amp;#39;);
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.be.above(2);
  });

  describe(&amp;#39;docs example 75&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(2).to.be.at.least(1); // Not recommended
    expect(2).to.be.at.least(2); // Not recommended
  });

  describe(&amp;#39;docs example 76&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf(3); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf.at.least(2); // Not recommended

    expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
    expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended
  });

  describe(&amp;#39;docs example 77&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.at.least(2); // Not recommended
  });

  describe(&amp;#39;docs example 78&amp;#39;, () =&amp;gt; {
    expect(1).to.be.at.least(2, &amp;#39;nooo why fail??&amp;#39;);
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.be.at.least(2);
  });

  describe(&amp;#39;docs example 79&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.be.below(2); // Not recommended
  });

  describe(&amp;#39;docs example 80&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf(3); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf.below(4); // Not recommended

    expect([1, 2, 3]).to.have.length(3); // Recommended
    expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended
  });

  describe(&amp;#39;docs example 81&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(2).to.not.be.below(1); // Not recommended
  });

  describe(&amp;#39;docs example 82&amp;#39;, () =&amp;gt; {
    expect(2).to.be.below(1, &amp;#39;nooo why fail??&amp;#39;);
    expect(2, &amp;#39;nooo why fail??&amp;#39;).to.be.below(1);
  });

  describe(&amp;#39;docs example 83&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.be.at.most(2); // Not recommended
    expect(1).to.be.at.most(1); // Not recommended
  });

  describe(&amp;#39;docs example 84&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf(3); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf.at.most(4); // Not recommended

    expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
    expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended
  });

  describe(&amp;#39;docs example 85&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(2).to.not.be.at.most(1); // Not recommended
  });

  describe(&amp;#39;docs example 86&amp;#39;, () =&amp;gt; {
    expect(2).to.be.at.most(1, &amp;#39;nooo why fail??&amp;#39;);
    expect(2, &amp;#39;nooo why fail??&amp;#39;).to.be.at.most(1);
  });

  describe(&amp;#39;docs example 87&amp;#39;, () =&amp;gt; {
    expect(2).to.equal(2); // Recommended
    expect(2).to.be.within(1, 3); // Not recommended
    expect(2).to.be.within(2, 3); // Not recommended
    expect(2).to.be.within(1, 2); // Not recommended
  });

  describe(&amp;#39;docs example 88&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf.within(2, 4); // Not recommended

    expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
    expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended
  });

  describe(&amp;#39;docs example 89&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.within(2, 4); // Not recommended
  });

  describe(&amp;#39;docs example 90&amp;#39;, () =&amp;gt; {
    expect(4).to.be.within(1, 3, &amp;#39;nooo why fail??&amp;#39;);
    expect(4, &amp;#39;nooo why fail??&amp;#39;).to.be.within(1, 3);
  });

  describe(&amp;#39;docs example 91&amp;#39;, () =&amp;gt; {
    function Cat() {}

    expect(new Cat()).to.be.an.instanceof(Cat);
    expect([1, 2]).to.be.an.instanceof(Array);
  });

  describe(&amp;#39;docs example 92&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.not.be.an.instanceof(Array);
  });

  describe(&amp;#39;docs example 93&amp;#39;, () =&amp;gt; {
    expect(1).to.be.an.instanceof(Array, &amp;#39;nooo why fail??&amp;#39;);
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.be.an.instanceof(Array);
  });

  describe(&amp;#39;docs example 94&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.have.property(&amp;#39;a&amp;#39;);
  });

  describe(&amp;#39;docs example 95&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.have.property(&amp;#39;a&amp;#39;, 1);
  });

  describe(&amp;#39;docs example 96&amp;#39;, () =&amp;gt; {
    // Target object deeply (but not strictly) has property `x: {a: 1}`
    expect({ x: { a: 1 } }).to.have.deep.property(&amp;#39;x&amp;#39;, { a: 1 });
    expect({ x: { a: 1 } }).to.not.have.property(&amp;#39;x&amp;#39;, { a: 1 });
  });

  describe(&amp;#39;docs example 97&amp;#39;, () =&amp;gt; {
    Object.prototype.b = 2;

    expect({ a: 1 }).to.have.own.property(&amp;#39;a&amp;#39;);
    expect({ a: 1 }).to.have.own.property(&amp;#39;a&amp;#39;, 1);
    expect({ a: 1 }).to.have.property(&amp;#39;b&amp;#39;);
    expect({ a: 1 }).to.not.have.own.property(&amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 98&amp;#39;, () =&amp;gt; {
    expect({ x: { a: 1 } }).to.have.deep.own.property(&amp;#39;x&amp;#39;, { a: 1 });
  });

  describe(&amp;#39;docs example 99&amp;#39;, () =&amp;gt; {
    expect({ a: { b: [&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;] } }).to.have.nested.property(&amp;#39;a.b[1]&amp;#39;);
    expect({ a: { b: [&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;] } }).to.have.nested.property(&amp;#39;a.b[1]&amp;#39;, &amp;#39;y&amp;#39;);
  });

  describe(&amp;#39;docs example 100&amp;#39;, () =&amp;gt; {
    expect({ &amp;#39;.a&amp;#39;: { &amp;#39;[b]&amp;#39;: &amp;#39;x&amp;#39; } }).to.have.nested.property(&amp;#39;\\.a.\\[b\\]&amp;#39;);
  });

  describe(&amp;#39;docs example 101&amp;#39;, () =&amp;gt; {
    expect({ a: { b: [{ c: 3 }] } }).to.have.deep.nested.property(&amp;#39;a.b[0]&amp;#39;, { c: 3 });
  });

  describe(&amp;#39;docs example 102&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.not.have.property(&amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 103&amp;#39;, () =&amp;gt; {
    expect({ b: 2 }).to.not.have.property(&amp;#39;a&amp;#39;); // Recommended
    expect({ b: 2 }).to.not.have.property(&amp;#39;a&amp;#39;, 1); // Not recommended
  });

  describe(&amp;#39;docs example 104&amp;#39;, () =&amp;gt; {
    expect({ a: 3 }).to.have.property(&amp;#39;a&amp;#39;, 3); // Recommended
    expect({ a: 3 }).to.not.have.property(&amp;#39;a&amp;#39;, 1); // Not recommended
  });

  describe(&amp;#39;docs example 105&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.have.property(&amp;#39;a&amp;#39;).that.is.a(&amp;#39;number&amp;#39;);
  });

  describe(&amp;#39;docs example 106&amp;#39;, () =&amp;gt; {
    // Recommended
    expect({ a: 1 }).to.have.property(&amp;#39;a&amp;#39;, 2, &amp;#39;nooo why fail??&amp;#39;);
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.have.property(&amp;#39;a&amp;#39;, 2);
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.have.property(&amp;#39;b&amp;#39;);

    // Not recommended
    expect({ a: 1 }).to.have.property(&amp;#39;b&amp;#39;, undefined, &amp;#39;nooo why fail??&amp;#39;);
  });

  describe(&amp;#39;docs example 107&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;);
  });

  describe(&amp;#39;docs example 108&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;, {
      configurable: true,
      enumerable: true,
      writable: true,
      value: 1,
    });
  });

  describe(&amp;#39;docs example 109&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.not.have.ownPropertyDescriptor(&amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 110&amp;#39;, () =&amp;gt; {
    // Recommended
    expect({ b: 2 }).to.not.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;);

    // Not recommended
    expect({ b: 2 }).to.not.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;, {
      configurable: true,
      enumerable: true,
      writable: true,
      value: 1,
    });
  });

  describe(&amp;#39;docs example 111&amp;#39;, () =&amp;gt; {
    // Recommended
    expect({ a: 3 }).to.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;, {
      configurable: true,
      enumerable: true,
      writable: true,
      value: 3,
    });

    // Not recommended
    expect({ a: 3 }).to.not.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;, {
      configurable: true,
      enumerable: true,
      writable: true,
      value: 1,
    });
  });

  describe(&amp;#39;docs example 112&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;).that.has.property(&amp;#39;enumerable&amp;#39;, true);
  });

  describe(&amp;#39;docs example 113&amp;#39;, () =&amp;gt; {
    // Recommended
    expect({ a: 1 }).to.have.ownPropertyDescriptor(
      &amp;#39;a&amp;#39;,
      {
        configurable: true,
        enumerable: true,
        writable: true,
        value: 2,
      },
      &amp;#39;nooo why fail??&amp;#39;
    );

    // Recommended
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.have.ownPropertyDescriptor(&amp;#39;a&amp;#39;, {
      configurable: true,
      enumerable: true,
      writable: true,
      value: 2,
    });

    // Recommended
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.have.ownPropertyDescriptor(&amp;#39;b&amp;#39;);

    // Not recommended
    expect({ a: 1 }).to.have.ownPropertyDescriptor(&amp;#39;b&amp;#39;, undefined, &amp;#39;nooo why fail??&amp;#39;);
  });

  describe(&amp;#39;docs example 114&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.have.lengthOf(3);
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf(3);
    expect(new Set([1, 2, 3])).to.have.lengthOf(3);
    expect(
      new Map([
        [&amp;#39;a&amp;#39;, 1],
        [&amp;#39;b&amp;#39;, 2],
        [&amp;#39;c&amp;#39;, 3],
      ])
    ).to.have.lengthOf(3);
  });

  describe(&amp;#39;docs example 115&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.have.lengthOf(3); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.not.have.lengthOf(4); // Not recommended
  });

  describe(&amp;#39;docs example 116&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.have.lengthOf(2, &amp;#39;nooo why fail??&amp;#39;);
    expect([1, 2, 3], &amp;#39;nooo why fail??&amp;#39;).to.have.lengthOf(2);
  });

  describe(&amp;#39;docs example 117&amp;#39;, () =&amp;gt; {
    // Recommended
    expect([1, 2, 3]).to.have.lengthOf(3);

    // Not recommended
    expect([1, 2, 3]).to.have.lengthOf.above(2);
    expect([1, 2, 3]).to.have.lengthOf.below(4);
    expect([1, 2, 3]).to.have.lengthOf.at.least(3);
    expect([1, 2, 3]).to.have.lengthOf.at.most(3);
    expect([1, 2, 3]).to.have.lengthOf.within(2, 4);
  });

  describe(&amp;#39;docs example 118&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error
    expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected
  });

  describe(&amp;#39;docs example 119&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.match(/^foo/);
  });

  describe(&amp;#39;docs example 120&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.not.match(/taco/);
  });

  describe(&amp;#39;docs example 121&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.match(/taco/, &amp;#39;nooo why fail??&amp;#39;);
    expect(&amp;#39;foobar&amp;#39;, &amp;#39;nooo why fail??&amp;#39;).to.match(/taco/);
  });

  describe(&amp;#39;docs example 122&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.have.string(&amp;#39;bar&amp;#39;);
  });

  describe(&amp;#39;docs example 123&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.not.have.string(&amp;#39;taco&amp;#39;);
  });

  describe(&amp;#39;docs example 124&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foobar&amp;#39;).to.have.string(&amp;#39;taco&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);
    expect(&amp;#39;foobar&amp;#39;, &amp;#39;nooo why fail??&amp;#39;).to.have.string(&amp;#39;taco&amp;#39;);
  });

  describe(&amp;#39;docs example 125&amp;#39;, () =&amp;gt; {
    expect({ a: 1, b: 2 }).to.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
    expect([&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;]).to.have.all.keys(0, 1);

    expect({ a: 1, b: 2 }).to.have.all.keys([&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;]);
    expect([&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;]).to.have.all.keys([0, 1]);

    expect({ a: 1, b: 2 }).to.have.all.keys({ a: 4, b: 5 }); // ignore 4 and 5
    expect([&amp;#39;x&amp;#39;, &amp;#39;y&amp;#39;]).to.have.all.keys({ 0: 4, 1: 5 }); // ignore 4 and 5
  });

  describe(&amp;#39;docs example 126&amp;#39;, () =&amp;gt; {
    expect(
      new Map([
        [&amp;#39;a&amp;#39;, 1],
        [&amp;#39;b&amp;#39;, 2],
      ])
    ).to.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
    expect(new Set([&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;])).to.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 127&amp;#39;, () =&amp;gt; {
    expect({ a: 1, b: 2 }).to.be.an(&amp;#39;object&amp;#39;).that.has.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 128&amp;#39;, () =&amp;gt; {
    // Target set deeply (but not strictly) has key `{a: 1}`
    expect(new Set([{ a: 1 }])).to.have.all.deep.keys([{ a: 1 }]);
    expect(new Set([{ a: 1 }])).to.not.have.all.keys([{ a: 1 }]);
  });

  describe(&amp;#39;docs example 129&amp;#39;, () =&amp;gt; {
    // Recommended; asserts that target doesn&amp;#39;t have any of the given keys
    expect({ a: 1, b: 2 }).to.not.have.any.keys(&amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;);

    // Not recommended; asserts that target doesn&amp;#39;t have all of the given
    // keys but may or may not have some of them
    expect({ a: 1, b: 2 }).to.not.have.all.keys(&amp;#39;c&amp;#39;, &amp;#39;d&amp;#39;);
  });

  describe(&amp;#39;docs example 130&amp;#39;, () =&amp;gt; {
    // Recommended; asserts that target has all the given keys
    expect({ a: 1, b: 2 }).to.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);

    // Not recommended; asserts that target has at least one of the given
    // keys but may or may not have more of them
    expect({ a: 1, b: 2 }).to.have.any.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 131&amp;#39;, () =&amp;gt; {
    // Both assertions are identical
    expect({ a: 1, b: 2 }).to.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;); // Recommended
    expect({ a: 1, b: 2 }).to.have.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 132&amp;#39;, () =&amp;gt; {
    // Target object&amp;#39;s keys are a superset of [&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;] but not identical
    expect({ a: 1, b: 2, c: 3 }).to.include.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
    expect({ a: 1, b: 2, c: 3 }).to.not.have.all.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 133&amp;#39;, () =&amp;gt; {
    // Both assertions are identical
    expect({ a: 1 }).to.have.any.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
    expect({ a: 1 }).to.include.any.keys(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 134&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.have.key(&amp;#39;b&amp;#39;);
  });

  describe(&amp;#39;docs example 135&amp;#39;, () =&amp;gt; {
    var badFn = function () {
      throw new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    };

    expect(badFn).to.throw();
  });

  describe(&amp;#39;docs example 136&amp;#39;, () =&amp;gt; {
    var badFn = function () {
      throw new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    };

    expect(badFn).to.throw(TypeError);
  });

  describe(&amp;#39;docs example 137&amp;#39;, () =&amp;gt; {
    var err = new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    var badFn = function () {
      throw err;
    };

    expect(badFn).to.throw(err);
  });

  describe(&amp;#39;docs example 138&amp;#39;, () =&amp;gt; {
    var badFn = function () {
      throw new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    };

    expect(badFn).to.throw(&amp;#39;salmon&amp;#39;);
  });

  describe(&amp;#39;docs example 139&amp;#39;, () =&amp;gt; {
    var badFn = function () {
      throw new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    };

    expect(badFn).to.throw(/salmon/);
  });

  describe(&amp;#39;docs example 140&amp;#39;, () =&amp;gt; {
    var err = new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    var badFn = function () {
      throw err;
    };

    expect(badFn).to.throw(TypeError, &amp;#39;salmon&amp;#39;);
    expect(badFn).to.throw(TypeError, /salmon/);
    expect(badFn).to.throw(err, &amp;#39;salmon&amp;#39;);
    expect(badFn).to.throw(err, /salmon/);
  });

  describe(&amp;#39;docs example 141&amp;#39;, () =&amp;gt; {
    var goodFn = function () {};

    expect(goodFn).to.not.throw();
  });

  describe(&amp;#39;docs example 142&amp;#39;, () =&amp;gt; {
    var goodFn = function () {};

    expect(goodFn).to.not.throw(); // Recommended
    expect(goodFn).to.not.throw(ReferenceError, &amp;#39;x&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 143&amp;#39;, () =&amp;gt; {
    var badFn = function () {
      throw new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    };

    expect(badFn).to.throw(TypeError, &amp;#39;salmon&amp;#39;); // Recommended
    expect(badFn).to.not.throw(ReferenceError, &amp;#39;x&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 144&amp;#39;, () =&amp;gt; {
    var err = new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    err.code = 42;
    var badFn = function () {
      throw err;
    };

    expect(badFn).to.throw(TypeError).with.property(&amp;#39;code&amp;#39;, 42);
  });

  describe(&amp;#39;docs example 145&amp;#39;, () =&amp;gt; {
    var goodFn = function () {};

    expect(goodFn).to.throw(TypeError, &amp;#39;x&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);
    expect(goodFn, &amp;#39;nooo why fail??&amp;#39;).to.throw();
  });

  describe(&amp;#39;docs example 146&amp;#39;, () =&amp;gt; {
    var fn = function () {
      throw new TypeError(&amp;#39;Illegal salmon!&amp;#39;);
    };

    expect(fn).to.throw(); // Good! Tests `fn` as desired
    expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn`
  });

  describe(&amp;#39;docs example 147&amp;#39;, () =&amp;gt; {
    expect(function () {
      fn(42);
    }).to.throw(); // Function expression
    expect(() =&amp;gt; fn(42)).to.throw(); // ES6 arrow function
  });

  describe(&amp;#39;docs example 148&amp;#39;, () =&amp;gt; {
    expect(function () {
      cat.meow();
    }).to.throw(); // Function expression
    expect(() =&amp;gt; cat.meow()).to.throw(); // ES6 arrow function
    expect(cat.meow.bind(cat)).to.throw(); // Bind
  });

  describe(&amp;#39;docs example 149&amp;#39;, () =&amp;gt; {
    function Cat() {}
    Cat.prototype.meow = function () {};

    expect(new Cat()).to.respondTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 150&amp;#39;, () =&amp;gt; {
    function Cat() {}
    Cat.prototype.meow = function () {};

    expect(Cat).to.respondTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 151&amp;#39;, () =&amp;gt; {
    function Cat() {}
    Cat.prototype.meow = function () {};
    Cat.hiss = function () {};

    expect(Cat).itself.to.respondTo(&amp;#39;hiss&amp;#39;).but.not.respondTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 152&amp;#39;, () =&amp;gt; {
    function Cat() {}
    Cat.prototype.meow = function () {};

    expect(new Cat()).to.be.an(&amp;#39;object&amp;#39;).that.respondsTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 153&amp;#39;, () =&amp;gt; {
    function Dog() {}
    Dog.prototype.bark = function () {};

    expect(new Dog()).to.not.respondTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 154&amp;#39;, () =&amp;gt; {
    expect({}).to.respondTo(&amp;#39;meow&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);
    expect({}, &amp;#39;nooo why fail??&amp;#39;).to.respondTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 155&amp;#39;, () =&amp;gt; {
    function Cat() {}
    Cat.prototype.meow = function () {};
    Cat.hiss = function () {};

    expect(Cat).itself.to.respondTo(&amp;#39;hiss&amp;#39;).but.not.respondTo(&amp;#39;meow&amp;#39;);
  });

  describe(&amp;#39;docs example 156&amp;#39;, () =&amp;gt; {
    expect(1).to.satisfy(function (num) {
      return num &amp;gt; 0;
    });
  });

  describe(&amp;#39;docs example 157&amp;#39;, () =&amp;gt; {
    expect(1).to.not.satisfy(function (num) {
      return num &amp;gt; 2;
    });
  });

  describe(&amp;#39;docs example 158&amp;#39;, () =&amp;gt; {
    expect(1).to.satisfy(function (num) {
      return num &amp;gt; 2;
    }, &amp;#39;nooo why fail??&amp;#39;);

    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.satisfy(function (num) {
      return num &amp;gt; 2;
    });
  });

  describe(&amp;#39;docs example 159&amp;#39;, () =&amp;gt; {
    // Recommended
    expect(1.5).to.equal(1.5);

    // Not recommended
    expect(1.5).to.be.closeTo(1, 0.5);
    expect(1.5).to.be.closeTo(2, 0.5);
    expect(1.5).to.be.closeTo(1, 1);
  });

  describe(&amp;#39;docs example 160&amp;#39;, () =&amp;gt; {
    expect(1.5).to.equal(1.5); // Recommended
    expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
  });

  describe(&amp;#39;docs example 161&amp;#39;, () =&amp;gt; {
    expect(1.5).to.be.closeTo(3, 1, &amp;#39;nooo why fail??&amp;#39;);
    expect(1.5, &amp;#39;nooo why fail??&amp;#39;).to.be.closeTo(3, 1);
  });

  describe(&amp;#39;docs example 162&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.have.members([2, 1, 3]);
    expect([1, 2, 2]).to.have.members([2, 1, 2]);
  });

  describe(&amp;#39;docs example 163&amp;#39;, () =&amp;gt; {
    // Target array deeply (but not strictly) has member `{a: 1}`
    expect([{ a: 1 }]).to.have.deep.members([{ a: 1 }]);
    expect([{ a: 1 }]).to.not.have.members([{ a: 1 }]);
  });

  describe(&amp;#39;docs example 164&amp;#39;, () =&amp;gt; {
    expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
    expect([1, 2, 3]).to.have.members([2, 1, 3]).but.not.ordered.members([2, 1, 3]);
  });

  describe(&amp;#39;docs example 165&amp;#39;, () =&amp;gt; {
    // Target array is a superset of [1, 2] but not identical
    expect([1, 2, 3]).to.include.members([1, 2]);
    expect([1, 2, 3]).to.not.have.members([1, 2]);

    // Duplicates in the subset are ignored
    expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
  });

  describe(&amp;#39;docs example 166&amp;#39;, () =&amp;gt; {
    expect([{ a: 1 }, { b: 2 }, { c: 3 }])
      .to.include.deep.ordered.members([{ a: 1 }, { b: 2 }])
      .but.not.include.deep.ordered.members([{ b: 2 }, { c: 3 }]);
  });

  describe(&amp;#39;docs example 167&amp;#39;, () =&amp;gt; {
    expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
    expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
  });

  describe(&amp;#39;docs example 168&amp;#39;, () =&amp;gt; {
    expect([1, 2]).to.have.members([1, 2, 3], &amp;#39;nooo why fail??&amp;#39;);
    expect([1, 2], &amp;#39;nooo why fail??&amp;#39;).to.have.members([1, 2, 3]);
  });

  describe(&amp;#39;docs example 169&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
  });

  describe(&amp;#39;docs example 170&amp;#39;, () =&amp;gt; {
    expect(1).to.equal(1); // Recommended
    expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
  });

  describe(&amp;#39;docs example 171&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;Today is sunny&amp;#39;).to.contain.oneOf([&amp;#39;sunny&amp;#39;, &amp;#39;cloudy&amp;#39;]);
    expect(&amp;#39;Today is rainy&amp;#39;).to.not.contain.oneOf([&amp;#39;sunny&amp;#39;, &amp;#39;cloudy&amp;#39;]);
    expect([1, 2, 3]).to.contain.oneOf([3, 4, 5]);
    expect([1, 2, 3]).to.not.contain.oneOf([4, 5, 6]);
  });

  describe(&amp;#39;docs example 172&amp;#39;, () =&amp;gt; {
    expect(1).to.be.oneOf([2, 3, 4], &amp;#39;nooo why fail??&amp;#39;);
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.be.oneOf([2, 3, 4]);
  });

  describe(&amp;#39;docs example 173&amp;#39;, () =&amp;gt; {
    var dots = &amp;#39;&amp;#39;,
      addDot = function () {
        dots &amp;#43;= &amp;#39;.&amp;#39;;
      },
      getDots = function () {
        return dots;
      };

    // Recommended
    expect(getDots()).to.equal(&amp;#39;&amp;#39;);
    addDot();
    expect(getDots()).to.equal(&amp;#39;.&amp;#39;);

    // Not recommended
    expect(addDot).to.change(getDots);
  });

  describe(&amp;#39;docs example 174&amp;#39;, () =&amp;gt; {
    var myObj = { dots: &amp;#39;&amp;#39; },
      addDot = function () {
        myObj.dots &amp;#43;= &amp;#39;.&amp;#39;;
      };

    // Recommended
    expect(myObj).to.have.property(&amp;#39;dots&amp;#39;, &amp;#39;&amp;#39;);
    addDot();
    expect(myObj).to.have.property(&amp;#39;dots&amp;#39;, &amp;#39;.&amp;#39;);

    // Not recommended
    expect(addDot).to.change(myObj, &amp;#39;dots&amp;#39;);
  });

  describe(&amp;#39;docs example 175&amp;#39;, () =&amp;gt; {
    var dots = &amp;#39;&amp;#39;,
      noop = function () {},
      getDots = function () {
        return dots;
      };

    expect(noop).to.not.change(getDots);

    var myObj = { dots: &amp;#39;&amp;#39; },
      noop = function () {};

    expect(noop).to.not.change(myObj, &amp;#39;dots&amp;#39;);
  });

  describe(&amp;#39;docs example 176&amp;#39;, () =&amp;gt; {
    var myObj = { dots: &amp;#39;&amp;#39; },
      addDot = function () {
        myObj.dots &amp;#43;= &amp;#39;.&amp;#39;;
      };

    expect(addDot).to.not.change(myObj, &amp;#39;dots&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);

    var dots = &amp;#39;&amp;#39;,
      addDot = function () {
        dots &amp;#43;= &amp;#39;.&amp;#39;;
      },
      getDots = function () {
        return dots;
      };

    expect(addDot, &amp;#39;nooo why fail??&amp;#39;).to.not.change(getDots);
  });

  describe(&amp;#39;docs example 177&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      },
      subtractTwo = function () {
        myObj.val -= 2;
      };

    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(addTwo).to.change(myObj, &amp;#39;val&amp;#39;).by(2); // Not recommended

    expect(subtractTwo).to.decrease(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(subtractTwo).to.change(myObj, &amp;#39;val&amp;#39;).by(2); // Not recommended
  });

  describe(&amp;#39;docs example 178&amp;#39;, () =&amp;gt; {
    var val = 1,
      addTwo = function () {
        val &amp;#43;= 2;
      },
      getVal = function () {
        return val;
      };

    expect(addTwo).to.increase(getVal).by(2); // Recommended
    expect(addTwo).to.increase(getVal); // Not recommended
  });

  describe(&amp;#39;docs example 179&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      };

    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 180&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      subtractTwo = function () {
        myObj.val -= 2;
      };

    expect(subtractTwo).to.decrease(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(subtractTwo).to.not.increase(myObj, &amp;#39;val&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 181&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      noop = function () {};

    expect(noop).to.not.change(myObj, &amp;#39;val&amp;#39;); // Recommended
    expect(noop).to.not.increase(myObj, &amp;#39;val&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 182&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      noop = function () {};

    expect(noop).to.increase(myObj, &amp;#39;val&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);

    var val = 1,
      noop = function () {},
      getVal = function () {
        return val;
      };

    expect(noop, &amp;#39;nooo why fail??&amp;#39;).to.increase(getVal);
  });

  describe(&amp;#39;docs example 183&amp;#39;, () =&amp;gt; {
    var val = 1,
      subtractTwo = function () {
        val -= 2;
      },
      getVal = function () {
        return val;
      };

    expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
    expect(subtractTwo).to.decrease(getVal); // Not recommended
  });

  describe(&amp;#39;docs example 184&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      subtractTwo = function () {
        myObj.val -= 2;
      };

    expect(subtractTwo).to.decrease(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(subtractTwo).to.decrease(myObj, &amp;#39;val&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 185&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      };

    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(addTwo).to.not.decrease(myObj, &amp;#39;val&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 186&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      noop = function () {};

    expect(noop).to.not.change(myObj, &amp;#39;val&amp;#39;); // Recommended
    expect(noop).to.not.decrease(myObj, &amp;#39;val&amp;#39;); // Not recommended
  });

  describe(&amp;#39;docs example 187&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      noop = function () {};

    expect(noop).to.decrease(myObj, &amp;#39;val&amp;#39;, &amp;#39;nooo why fail??&amp;#39;);

    var val = 1,
      noop = function () {},
      getVal = function () {
        return val;
      };

    expect(noop, &amp;#39;nooo why fail??&amp;#39;).to.decrease(getVal);
  });

  describe(&amp;#39;docs example 188&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      };

    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(2);
  });

  describe(&amp;#39;docs example 189&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      subtractTwo = function () {
        myObj.val -= 2;
      };

    expect(subtractTwo).to.decrease(myObj, &amp;#39;val&amp;#39;).by(2);
  });

  describe(&amp;#39;docs example 190&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      },
      subtractTwo = function () {
        myObj.val -= 2;
      };

    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(addTwo).to.change(myObj, &amp;#39;val&amp;#39;).by(2); // Not recommended

    expect(subtractTwo).to.decrease(myObj, &amp;#39;val&amp;#39;).by(2); // Recommended
    expect(subtractTwo).to.change(myObj, &amp;#39;val&amp;#39;).by(2); // Not recommended
  });

  describe(&amp;#39;docs example 191&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      };

    // Recommended
    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(2);

    // Not recommended
    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).but.not.by(3);
  });

  describe(&amp;#39;docs example 192&amp;#39;, () =&amp;gt; {
    var myObj = { val: 1 },
      addTwo = function () {
        myObj.val &amp;#43;= 2;
      };

    expect(addTwo).to.increase(myObj, &amp;#39;val&amp;#39;).by(3, &amp;#39;nooo why fail??&amp;#39;);
    expect(addTwo, &amp;#39;nooo why fail??&amp;#39;).to.increase(myObj, &amp;#39;val&amp;#39;).by(3);
  });

  describe(&amp;#39;docs example 193&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.be.extensible;
  });

  describe(&amp;#39;docs example 194&amp;#39;, () =&amp;gt; {
    var nonExtensibleObject = Object.preventExtensions({}),
      sealedObject = Object.seal({}),
      frozenObject = Object.freeze({});

    expect(nonExtensibleObject).to.not.be.extensible;
    expect(sealedObject).to.not.be.extensible;
    expect(frozenObject).to.not.be.extensible;
    expect(1).to.not.be.extensible;
  });

  describe(&amp;#39;docs example 195&amp;#39;, () =&amp;gt; {
    expect(1, &amp;#39;nooo why fail??&amp;#39;).to.be.extensible;
  });

  describe(&amp;#39;docs example 196&amp;#39;, () =&amp;gt; {
    var sealedObject = Object.seal({});
    var frozenObject = Object.freeze({});

    expect(sealedObject).to.be.sealed;
    expect(frozenObject).to.be.sealed;
    expect(1).to.be.sealed;
  });

  describe(&amp;#39;docs example 197&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.not.be.sealed;
  });

  describe(&amp;#39;docs example 198&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.be.sealed;
  });

  describe(&amp;#39;docs example 199&amp;#39;, () =&amp;gt; {
    var frozenObject = Object.freeze({});

    expect(frozenObject).to.be.frozen;
    expect(1).to.be.frozen;
  });

  describe(&amp;#39;docs example 200&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }).to.not.be.frozen;
  });

  describe(&amp;#39;docs example 201&amp;#39;, () =&amp;gt; {
    expect({ a: 1 }, &amp;#39;nooo why fail??&amp;#39;).to.be.frozen;
  });

  describe(&amp;#39;docs example 202&amp;#39;, () =&amp;gt; {
    expect(1).to.be.finite;
  });

  describe(&amp;#39;docs example 203&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;).to.be.a(&amp;#39;string&amp;#39;); // Recommended
    expect(&amp;#39;foo&amp;#39;).to.not.be.finite; // Not recommended
  });

  describe(&amp;#39;docs example 204&amp;#39;, () =&amp;gt; {
    expect(NaN).to.be.NaN; // Recommended
    expect(NaN).to.not.be.finite; // Not recommended
  });

  describe(&amp;#39;docs example 205&amp;#39;, () =&amp;gt; {
    expect(Infinity).to.equal(Infinity); // Recommended
    expect(Infinity).to.not.be.finite; // Not recommended
  });

  describe(&amp;#39;docs example 206&amp;#39;, () =&amp;gt; {
    expect(-Infinity).to.equal(-Infinity); // Recommended
    expect(-Infinity).to.not.be.finite; // Not recommended
  });

  describe(&amp;#39;docs example 207&amp;#39;, () =&amp;gt; {
    expect(&amp;#39;foo&amp;#39;, &amp;#39;nooo why fail??&amp;#39;).to.be.finite;
  });

  describe(&amp;#39;docs example 208&amp;#39;, () =&amp;gt; {
    expect.fail();
    expect.fail(&amp;#39;custom error message&amp;#39;);
    expect.fail(1, 2);
    expect.fail(1, 2, &amp;#39;custom error message&amp;#39;);
    expect.fail(1, 2, &amp;#39;custom error message&amp;#39;, &amp;#39;&amp;gt;&amp;#39;);
    expect.fail(1, 2, undefined, &amp;#39;&amp;gt;&amp;#39;);
  });

  // describe(&amp;#39;docs example 209&amp;#39;, () =&amp;gt; {
  //   should.fail();
  //   should.fail(&amp;#34;custom error message&amp;#34;);
  //   should.fail(1, 2);
  //   should.fail(1, 2, &amp;#34;custom error message&amp;#34;);
  //   should.fail(1, 2, &amp;#34;custom error message&amp;#34;, &amp;#34;&amp;gt;&amp;#34;);
  //   should.fail(1, 2, undefined, &amp;#34;&amp;gt;&amp;#34;);

  // });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="functional-testing">Functional testing&lt;/h1>
&lt;h3 id="most-basic-integration-test">Most basic integration test&lt;/h3>
&lt;!-- eslint-skip -->
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import http from &amp;#39;k6/http&amp;#39;;
import { describe, expect } from &amp;#39;https://jslib.k6.io/k6chaijs/4.3.4.3/index.js&amp;#39;;
export const options = {
thresholds: {
checks: [&amp;#39;rate == 1.00&amp;#39;],
},
};
export default function () {
describe(&amp;#39;Hello world!&amp;#39;, () =&amp;gt; {
const response = http.get(&amp;#39;https://quickpizza.grafana.com/api/ratings&amp;#39;, {
headers: { Authorization: &amp;#39;Token abcdef0123456789&amp;#39; },
});
expect(response.status, &amp;#39;response status&amp;#39;).to.equal(200);
expect(response).to.have.validJsonBody();
expect(response.json(&amp;#39;ratings&amp;#39;), &amp;#39;ratings list&amp;#39;).to.be.an(&amp;#39;array&amp;#39;);
});
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;h3 id="sample-integration-test">Sample integration test&lt;/h3>
&lt;p>This test goes through several steps. It creates a new user account, authenticates, and interacts with protected resources.&lt;/p></description></item><item><title>Track transmitted data per URL</title><link>https://grafana.com/docs/k6/v2.3.x/examples/track-transmitted-data-per-url/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/track-transmitted-data-per-url/</guid><content><![CDATA[&lt;h1 id=&#34;track-transmitted-data-per-url&#34;&gt;Track transmitted data per URL&lt;/h1&gt;
&lt;p&gt;By default, k6 collects automatically two 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/metrics/#built-in-metrics&#34;&gt;built-in metrics&lt;/a&gt; related to the transmitted data during the test execution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;data_received&lt;/code&gt;: the amount of received data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data_sent&lt;/code&gt;: the amount of data sent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the reported values of these metrics don&amp;rsquo;t tag the particular request or URL. Therefore, you cannot know the amount of data transmitted for a specific request or URL.&lt;/p&gt;
&lt;p&gt;This example shows how to track data sent and received for an individual URL.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;
import { Counter } from &amp;#39;k6/metrics&amp;#39;;

// Two custom metrics to track data sent and received. We will tag data points added with the corresponding URL
// so we can filter these metrics down to see the data for individual URLs and set threshold across all or per-URL as well.
export const epDataSent = new Counter(&amp;#39;endpoint_data_sent&amp;#39;);
export const epDataRecv = new Counter(&amp;#39;endpoint_data_recv&amp;#39;);

export const options = {
  duration: &amp;#39;10s&amp;#39;,
  vus: 10,
  thresholds: {
    // We can setup thresholds on these custom metrics, &amp;#34;count&amp;#34; means bytes in this case.
    &amp;#39;endpoint_data_sent&amp;#39;: [&amp;#39;count &amp;lt; 2048&amp;#39;],

    // The above threshold would look at all data points added to the custom metric.
    // If we want to only consider data points for a particular URL/endpoint we can filter by URL.
    &amp;#39;endpoint_data_sent{url:https://test.k6.io/contacts.php}&amp;#39;: [&amp;#39;count &amp;lt; 1024&amp;#39;],
    &amp;#39;endpoint_data_recv{url:https://test.k6.io/}&amp;#39;: [&amp;#39;count &amp;lt; 2048&amp;#39;], // &amp;#34;count&amp;#34; means bytes in this case
  },
};

function sizeOfHeaders(hdrs) {
  return Object.keys(hdrs).reduce((sum, key) =&amp;gt; sum &amp;#43; key.length &amp;#43; hdrs[key].length, 0);
}

function trackDataMetricsPerURL(res) {
  // Add data points for sent and received data
  epDataSent.add(sizeOfHeaders(res.request.headers) &amp;#43; res.request.body.length, {
    url: res.url,
  });
  epDataRecv.add(sizeOfHeaders(res.headers) &amp;#43; res.body.length, {
    url: res.url,
  });
}

export default function () {
  let res;

  res = http.get(&amp;#39;https://test.k6.io/&amp;#39;);
  trackDataMetricsPerURL(res);

  res = http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
  trackDataMetricsPerURL(res);

  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="track-transmitted-data-per-url">Track transmitted data per URL&lt;/h1>
&lt;p>By default, k6 collects automatically two
&lt;a href="/docs/k6/v2.3.x/using-k6/metrics/#built-in-metrics">built-in metrics&lt;/a> related to the transmitted data during the test execution:&lt;/p>
&lt;ul>
&lt;li>&lt;code>data_received&lt;/code>: the amount of received data.&lt;/li>
&lt;li>&lt;code>data_sent&lt;/code>: the amount of data sent.&lt;/li>
&lt;/ul>
&lt;p>However, the reported values of these metrics don&amp;rsquo;t tag the particular request or URL. Therefore, you cannot know the amount of data transmitted for a specific request or URL.&lt;/p></description></item><item><title>URLs with query parameters</title><link>https://grafana.com/docs/k6/v2.3.x/examples/url-query-parameters/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/url-query-parameters/</guid><content><![CDATA[&lt;h1 id=&#34;urls-with-query-parameters&#34;&gt;URLs with query parameters&lt;/h1&gt;
&lt;p&gt;How to use &lt;strong&gt;URL&lt;/strong&gt; and &lt;strong&gt;URLSearchParams&lt;/strong&gt; imported from &lt;a href=&#34;https://jslib.k6.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;jslib.k6.io&lt;/a&gt; to construct URLs with/without query parameters.&lt;/p&gt;
&lt;h2 id=&#34;url&#34;&gt;URL&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { URL } from &amp;#39;https://jslib.k6.io/url/1.0.0/index.js&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;

export default function () {
  const url = new URL(&amp;#39;https://k6.io&amp;#39;);

  url.searchParams.append(&amp;#39;utm_medium&amp;#39;, &amp;#39;organic&amp;#39;);
  url.searchParams.append(&amp;#39;utm_source&amp;#39;, &amp;#39;test&amp;#39;);
  url.searchParams.append(&amp;#39;multiple&amp;#39;, [&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;]);

  const res = http.get(url.toString());
  // https://k6.io?utm_medium=organic&amp;amp;utm_source=test&amp;amp;multiple=foo%2Cbar
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- vale off --&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;URLSearchParams(init)&lt;/td&gt;
              &lt;td&gt;Constructor&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;init&lt;/code&gt; Optional: One of [USVString, sequence of pairs or record ]&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;toString()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns a USVString containing the whole URL&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;hash&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing a &amp;lsquo;#&amp;rsquo; followed by the fragment identifier of the URL.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;host&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing the host, that is the &lt;code&gt;hostname&lt;/code&gt;, and then, if the port of the URL is nonempty, a &amp;lsquo;:&amp;rsquo;, followed by the &lt;code&gt;port&lt;/code&gt; of the URL.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;hostname&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Glossary/Domain_name&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;domain name&lt;/a&gt; of the URL.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;href&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;Returns a USVString containing the whole URL.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;origin&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;Returns a USVString containing the origin of the URL, that is its scheme, its domain and its port.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;password&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing the password specified before the domain name.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;pathname&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;Is a USVString containing an initial &amp;lsquo;/&amp;rsquo; followed by the path of the URL, not including the query string or fragment.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;port&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing the port number of the URL.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;protocol&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing the protocol scheme of the URL, including the final &amp;lsquo;:&amp;rsquo;.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;search&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString indicating the URL&amp;rsquo;s parameter string; if any parameters are provided, this string includes all of them, beginning with the leading ? character.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;searchParams&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A &lt;a href=&#34;#urlsearchparams&#34;&gt;URLSearchParams&lt;/a&gt; object which can be used to access the individual query parameters found in search.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;username&lt;/td&gt;
              &lt;td&gt;Property&lt;/td&gt;
              &lt;td&gt;A USVString containing the username specified before the domain name.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;!-- vale on --&gt;
&lt;h2 id=&#34;urlsearchparams&#34;&gt;URLSearchParams&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { URLSearchParams } from &amp;#39;https://jslib.k6.io/url/1.0.0/index.js&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;

export default function () {
  const searchParams = new URLSearchParams([
    [&amp;#39;utm_medium&amp;#39;, &amp;#39;organic&amp;#39;],
    [&amp;#39;utm_source&amp;#39;, &amp;#39;test&amp;#39;],
    [&amp;#39;multiple&amp;#39;, &amp;#39;foo&amp;#39;],
    [&amp;#39;multiple&amp;#39;, &amp;#39;bar&amp;#39;],
  ]);

  const res = http.get(`${&amp;#39;https://k6.io&amp;#39;}?${searchParams.toString()}`);
  // https://k6.io?utm_medium=organic&amp;amp;utm_source=test&amp;amp;multiple=foo&amp;amp;multiple=bar
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;URLSearchParams(init)&lt;/td&gt;
              &lt;td&gt;Constructor&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;init&lt;/code&gt; Optional: One of [USVString, sequence of pairs or record ]&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;toString()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns a query string (questionmark is omitted).&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;append()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Appends a specified key/value pair as a new search parameter.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;delete()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Deletes the given search parameter, and its associated value, from the list of all search parameters.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;entries()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns an iterator allowing iteration through all key/value pairs contained in this object.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;forEach()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Allows iteration through all values contained in this object via a callback function. &lt;code&gt;callback(value, key)&lt;/code&gt;.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;get()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns the first value associated with the given search parameter.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;getAll()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns all the values associated with a given search parameter.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;has()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns a Boolean that indicates whether a parameter with the specified name exists.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;keys()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns an iterator allowing iteration through all keys of the key/value pairs contained in this object.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;values()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Returns an iterator allowing iteration through all values of the key/value pairs contained in this object.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;set()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Sets the value associated with a given search parameter to the given value. If there were several matching values, this method deletes the others. If the search parameter doesn&amp;rsquo;t exist, this method creates it.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;sort()&lt;/td&gt;
              &lt;td&gt;Method&lt;/td&gt;
              &lt;td&gt;Sorts all key/value pairs, if any, by their keys.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;]]></content><description>&lt;h1 id="urls-with-query-parameters">URLs with query parameters&lt;/h1>
&lt;p>How to use &lt;strong>URL&lt;/strong> and &lt;strong>URLSearchParams&lt;/strong> imported from &lt;a href="https://jslib.k6.io/" target="_blank" rel="noopener noreferrer">jslib.k6.io&lt;/a> to construct URLs with/without query parameters.&lt;/p>
&lt;h2 id="url">URL&lt;/h2>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { URL } from &amp;#39;https://jslib.k6.io/url/1.0.0/index.js&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;
export default function () {
const url = new URL(&amp;#39;https://k6.io&amp;#39;);
url.searchParams.append(&amp;#39;utm_medium&amp;#39;, &amp;#39;organic&amp;#39;);
url.searchParams.append(&amp;#39;utm_source&amp;#39;, &amp;#39;test&amp;#39;);
url.searchParams.append(&amp;#39;multiple&amp;#39;, [&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;]);
const res = http.get(url.toString());
// https://k6.io?utm_medium=organic&amp;amp;utm_source=test&amp;amp;multiple=foo%2Cbar
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;!-- vale off -->
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>URLSearchParams(init)&lt;/td>
&lt;td>Constructor&lt;/td>
&lt;td>&lt;code>init&lt;/code> Optional: One of [USVString, sequence of pairs or record ]&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>toString()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns a USVString containing the whole URL&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hash&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing a &amp;lsquo;#&amp;rsquo; followed by the fragment identifier of the URL.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>host&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing the host, that is the &lt;code>hostname&lt;/code>, and then, if the port of the URL is nonempty, a &amp;lsquo;:&amp;rsquo;, followed by the &lt;code>port&lt;/code> of the URL.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hostname&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing the &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Domain_name" target="_blank" rel="noopener noreferrer">domain name&lt;/a> of the URL.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>href&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>Returns a USVString containing the whole URL.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>origin&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>Returns a USVString containing the origin of the URL, that is its scheme, its domain and its port.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>password&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing the password specified before the domain name.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>pathname&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>Is a USVString containing an initial &amp;lsquo;/&amp;rsquo; followed by the path of the URL, not including the query string or fragment.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>port&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing the port number of the URL.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>protocol&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing the protocol scheme of the URL, including the final &amp;lsquo;:&amp;rsquo;.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>search&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString indicating the URL&amp;rsquo;s parameter string; if any parameters are provided, this string includes all of them, beginning with the leading ? character.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>searchParams&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A &lt;a href="#urlsearchparams">URLSearchParams&lt;/a> object which can be used to access the individual query parameters found in search.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>username&lt;/td>
&lt;td>Property&lt;/td>
&lt;td>A USVString containing the username specified before the domain name.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section>&lt;!-- vale on -->
&lt;h2 id="urlsearchparams">URLSearchParams&lt;/h2>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { URLSearchParams } from &amp;#39;https://jslib.k6.io/url/1.0.0/index.js&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;
export default function () {
const searchParams = new URLSearchParams([
[&amp;#39;utm_medium&amp;#39;, &amp;#39;organic&amp;#39;],
[&amp;#39;utm_source&amp;#39;, &amp;#39;test&amp;#39;],
[&amp;#39;multiple&amp;#39;, &amp;#39;foo&amp;#39;],
[&amp;#39;multiple&amp;#39;, &amp;#39;bar&amp;#39;],
]);
const res = http.get(`${&amp;#39;https://k6.io&amp;#39;}?${searchParams.toString()}`);
// https://k6.io?utm_medium=organic&amp;amp;utm_source=test&amp;amp;multiple=foo&amp;amp;multiple=bar
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>URLSearchParams(init)&lt;/td>
&lt;td>Constructor&lt;/td>
&lt;td>&lt;code>init&lt;/code> Optional: One of [USVString, sequence of pairs or record ]&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>toString()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns a query string (questionmark is omitted).&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>append()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Appends a specified key/value pair as a new search parameter.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>delete()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Deletes the given search parameter, and its associated value, from the list of all search parameters.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>entries()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns an iterator allowing iteration through all key/value pairs contained in this object.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>forEach()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Allows iteration through all values contained in this object via a callback function. &lt;code>callback(value, key)&lt;/code>.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>get()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns the first value associated with the given search parameter.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>getAll()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns all the values associated with a given search parameter.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>has()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns a Boolean that indicates whether a parameter with the specified name exists.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>keys()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns an iterator allowing iteration through all keys of the key/value pairs contained in this object.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>values()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Returns an iterator allowing iteration through all values of the key/value pairs contained in this object.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>set()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Sets the value associated with a given search parameter to the given value. If there were several matching values, this method deletes the others. If the search parameter doesn&amp;rsquo;t exist, this method creates it.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>sort()&lt;/td>
&lt;td>Method&lt;/td>
&lt;td>Sorts all key/value pairs, if any, by their keys.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section></description></item><item><title>Instant load increase</title><link>https://grafana.com/docs/k6/v2.3.x/examples/instant-load-increase/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/instant-load-increase/</guid><content><![CDATA[&lt;h1 id=&#34;instant-load-increase&#34;&gt;Instant load increase&lt;/h1&gt;
&lt;p&gt;One of the common usages of performance testing tools it&amp;rsquo;s the so-called stepped arrival rate.&lt;/p&gt;
&lt;p&gt;In k6, you can do that by using the &lt;code&gt;options&lt;/code&gt; object, and configuring the number of iterations or VUs in different scenarios.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example on how to instantly increase the number of iterations and hold them for a period of time.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export const options = {
  scenarios: {
    contacts: {
      executor: &amp;#39;ramping-arrival-rate&amp;#39;,
      preAllocatedVUs: 50,
      timeUnit: &amp;#39;1s&amp;#39;,
      startRate: 50,
      stages: [
        { target: 200, duration: &amp;#39;30s&amp;#39; }, // linearly go from 50 iters/s to 200 iters/s for 30s
        { target: 500, duration: &amp;#39;0&amp;#39; }, // instantly jump to 500 iters/s
        { target: 500, duration: &amp;#39;10m&amp;#39; }, // continue with 500 iters/s for 10 minutes
      ],
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io&amp;#39;);
  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;rsquo;s an example on how to instantly increase the number of VUs and hold them for a period of time.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export const options = {
  scenarios: {
    contacts: {
      executor: &amp;#39;ramping-vus&amp;#39;,
      startVUs: 3,
      stages: [
        { target: 20, duration: &amp;#39;30s&amp;#39; }, // linearly go from 3 VUs to 20 VUs for 30s
        { target: 100, duration: &amp;#39;0&amp;#39; }, // instantly jump to 100 VUs
        { target: 100, duration: &amp;#39;10m&amp;#39; }, // continue with 100 VUs for 10 minutes
      ],
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io&amp;#39;);
  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="instant-load-increase">Instant load increase&lt;/h1>
&lt;p>One of the common usages of performance testing tools it&amp;rsquo;s the so-called stepped arrival rate.&lt;/p>
&lt;p>In k6, you can do that by using the &lt;code>options&lt;/code> object, and configuring the number of iterations or VUs in different scenarios.&lt;/p></description></item><item><title>Get timings for an HTTP metric</title><link>https://grafana.com/docs/k6/v2.3.x/examples/get-timings-for-an-http-metric/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/get-timings-for-an-http-metric/</guid><content><![CDATA[&lt;h1 id=&#34;get-timings-for-an-http-metric&#34;&gt;Get timings for an HTTP metric&lt;/h1&gt;
&lt;p&gt;To access the timing information from an individual HTTP request, the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/response/&#34;&gt;Response.timings&lt;/a&gt; object provides the time spent on the various phases in &lt;code&gt;ms&lt;/code&gt;.
One use case of this is to use the timings in a 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/metrics/create-custom-metrics/&#34;&gt;Custom metric&lt;/a&gt; to make a trend for a specific endpoint.&lt;/p&gt;
&lt;p&gt;The timings are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;blocked: equals to &lt;code&gt;http_req_blocked&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;connecting: equals to &lt;code&gt;http_req_connecting&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;tls_handshaking: equals to &lt;code&gt;http_req_tls_handshaking&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;sending: equals to &lt;code&gt;http_req_sending&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;waiting: equals to &lt;code&gt;http_req_waiting&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;receiving: equals to &lt;code&gt;http_req_receiving&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;duration: equals to &lt;code&gt;http_req_duration&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This script gets the request duration timing for a specific GET request and logs it to the console.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

export default function () {
  const res = http.get(&amp;#39;https://quickpizza.grafana.com/&amp;#39;);
  console.log(&amp;#39;Response time was &amp;#39; &amp;#43; String(res.timings.duration) &amp;#43; &amp;#39; ms&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The expected (partial) output looks like this:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;$ k6 run script.js

  INFO[0001] Response time was 337.962473 ms               source=console&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="get-timings-for-an-http-metric">Get timings for an HTTP metric&lt;/h1>
&lt;p>To access the timing information from an individual HTTP request, the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-http/response/">Response.timings&lt;/a> object provides the time spent on the various phases in &lt;code>ms&lt;/code>.
One use case of this is to use the timings in a
&lt;a href="/docs/k6/v2.3.x/using-k6/metrics/create-custom-metrics/">Custom metric&lt;/a> to make a trend for a specific endpoint.&lt;/p></description></item><item><title>Distribute workloads across VUs</title><link>https://grafana.com/docs/k6/v2.3.x/examples/distribute-workloads/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/distribute-workloads/</guid><content><![CDATA[&lt;h1 id=&#34;distribute-workloads-across-vus&#34;&gt;Distribute workloads across VUs&lt;/h1&gt;
&lt;p&gt;k6 can schedule different load patterns for different VU functions.
A test with multiple workloads might better simulate traffic in the real world, where user behavior is rarely uniform.
For example, most traffic to an e-commerce site might come from users who only search for items and read reviews. A small percentage of users might actively shop, performing actions that involve writes to the database and calls to different APIs.&lt;/p&gt;
&lt;p&gt;The following sections provide examples of how to structure k6 scripts to split logic across VUs.
To inspect the results for a certain behavior, you can 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/metrics/create-custom-metrics/&#34;&gt;create a custom metric&lt;/a&gt; or use 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/tags-and-groups/&#34;&gt;Tags&lt;/a&gt; to filter by scenario, code block, or individual request.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;These techniques can create very complex configurations.
However, more complexity creates more ambiguity in result interpretation&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;split-logic-across-scenarios&#34;&gt;Split logic across scenarios&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;In this context, &lt;em&gt;workload&lt;/em&gt; refers to the traffic pattern simulated by a scenario.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;One way to distribute traffic is to use scenarios to schedule different workloads for different functions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define multiple scenarios in your 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/k6-options/&#34;&gt;options&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use the scenario &lt;code&gt;exec&lt;/code&gt; property to execute different VU functions with a workload.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For example, imagine a social media site that typically receives 100 concurrent users.
Of those, 80 might visit their contacts page, and 20 might view the news.
To configure such a distribution, make two scenarios with different throughput or VUs:&lt;/p&gt;
&lt;!-- md-k6:fixedscenarios --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

export const options = {
  //scenario to view contacts
  scenarios: {
    contacts: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      exec: &amp;#39;contacts&amp;#39;,
      vus: 80,
      iterations: 100,
    },
    //scenario to view news
    news: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      exec: &amp;#39;news&amp;#39;,
      vus: 20,
      iterations: 100,
    },
  },
};

//use the exec property to run different scenarios for different functions

export function contacts() {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
}

export function news() {
  http.get(&amp;#39;https://test.k6.io/news.php&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To run only the contacts workload while developing it, 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#run-selected-scenarios&#34;&gt;select that scenario&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;k6 run --scenario contacts script.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This keeps the contacts scenario&amp;rsquo;s 80 VUs and 100 total iterations. Without &lt;code&gt;--scenario&lt;/code&gt;, both workloads run.&lt;/p&gt;
&lt;p&gt;To view granular results for a specific scenario, you can filter by the built-in scenario 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/tags-and-groups/&#34;&gt;tag&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;distribute-logic-by-vu-id&#34;&gt;Distribute logic by VU ID&lt;/h2&gt;
&lt;p&gt;In some cases, writing a scenario for each behavior might be inconvenient or impractical.
As an alternative, you can distribute logic across a range of VUs with the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/execution-context-variables/&#34;&gt;execution context variables&lt;/a&gt; from the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-execution/&#34;&gt;&lt;code&gt;k6/execution&lt;/code&gt;&lt;/a&gt; module.
With the &lt;code&gt;exec&lt;/code&gt; object, you can scope logic to a specific instance, scenario, or across all VUs.&lt;/p&gt;
&lt;p&gt;For example, this statement assigns behavior to the first 25 VUs in a test.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;if (exec.vu.idInTest &amp;lt;= 25) {
   //do something;
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more flexibility, you can use modulo expressions to distribute VUs according to percentages.
For example, the following script distributes logic according to different user profiles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;40 percent of users check the news.&lt;/li&gt;
&lt;li&gt;60 percent play a coinflip game.
&lt;ul&gt;
&lt;li&gt;Half bet &lt;code&gt;heads&lt;/code&gt;, and half bet &lt;code&gt;tails&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import exec from &amp;#39;k6/execution&amp;#39;;

export const options = {
  scenarios: {
    quickRamp: {
      executor: &amp;#39;ramping-arrival-rate&amp;#39;,
      startRate: 0,
      timeUnit: &amp;#39;1s&amp;#39;,
      preAllocatedVUs: 100,
      stages: [
        { target: 10, duration: &amp;#39;10s&amp;#39; },
        { target: 10, duration: &amp;#39;15s&amp;#39; },
        { target: 0, duration: &amp;#39;5s&amp;#39; },
      ],
    },
  },
};

export default function () {
  if (exec.vu.idInTest % 10 &amp;lt; 4) {
    // 0-3 range, read the news
    http.get(&amp;#39;http://test.k6.io/news&amp;#39;);
  } else if (exec.vu.idInTest % 10 &amp;lt; 7) {
    // 4-6 range, bet heads
    http.get(&amp;#39;http://test.k6.io/flip_coin.php?bet=heads&amp;#39;);
  } else {
    // 7-9 range, bet tails
    http.get(&amp;#39;http://test.k6.io/flip_coin.php?bet=tails&amp;#39;);
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To view results for a specific request or group, you can define 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/tags-and-groups/&#34;&gt;tags&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;randomize-behavior&#34;&gt;Randomize behavior&lt;/h2&gt;
&lt;p&gt;To add a degree of random behavior, consider one of the randomizing functions from the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/&#34;&gt;k6 utils&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, this script randomly assigns one behavior to happen one-third of the time, and another to happen all other times.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { sleep } from &amp;#39;k6&amp;#39;;
import { randomIntBetween } from &amp;#39;https://jslib.k6.io/k6-utils/1.2.0/index.js&amp;#39;;

export default function () {
  if (randomIntBetween(1, 3) % 3 &amp;gt; 1) {
    console.log(&amp;#39;1 in 3 times&amp;#39;);
  } else {
    console.log(&amp;#39;2 in 3 times&amp;#39;);
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For a more sophisticated example of randomizing, read this &lt;a href=&#34;https://community.grafana.com/t/how-to-distribute-vus-across-different-scenarios-with-k6/97698/17&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;forum post&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h1 id="distribute-workloads-across-vus">Distribute workloads across VUs&lt;/h1>
&lt;p>k6 can schedule different load patterns for different VU functions.
A test with multiple workloads might better simulate traffic in the real world, where user behavior is rarely uniform.
For example, most traffic to an e-commerce site might come from users who only search for items and read reviews. A small percentage of users might actively shop, performing actions that involve writes to the database and calls to different APIs.&lt;/p></description></item><item><title>Error handler</title><link>https://grafana.com/docs/k6/v2.3.x/examples/error-handler/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/error-handler/</guid><content><![CDATA[&lt;h1 id=&#34;error-handler&#34;&gt;Error handler&lt;/h1&gt;
&lt;p&gt;When encountering errors from an application&amp;rsquo;s backend, gathering additional error information, such as error messages, tracing data, or request and response bodies, is often necessary. The initial suggestion is to leverage your observability solution to find these errors. However, capturing error details directly in k6 can also be useful for troubleshooting.&lt;/p&gt;
&lt;p&gt;In k6, there are two common approaches to store additional error information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Console logs and output &lt;a href=&#34;https://k6.io/blog/using-loki-to-store-and-query-k6-logs/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;k6 logs to Loki&lt;/a&gt;, a file, or use &lt;a href=&#34;/docs/grafana-cloud/k6/analyze-results/inspect-test-results/inspect-logs/&#34;&gt;Grafana Cloud k6&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Using 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/tags-and-groups/&#34;&gt;Tags&lt;/a&gt; in a 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/metrics/create-custom-metrics/&#34;&gt;custom counter metric&lt;/a&gt; to track error data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When deciding what error data to store, consider whether it&amp;rsquo;s a general or specific error, and be aware that high-load tests may generate a substantial volume of error data.&lt;/p&gt;
&lt;p&gt;Below is an example using an &lt;code&gt;ErrorHandler&lt;/code&gt; class to log error information. It accepts a callback that instructs how to log errors. The example provides instructions for both previously mentioned options: console logs and custom metrics.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

// General error handler to log error details.
class ErrorHandler {
  // Instruct the error handler how to log errors
  constructor(logErrorDetails) {
    this.logErrorDetails = logErrorDetails;
  }

  // Logs response error details if isError is true.
  logError(isError, res, tags = {}) {
    if (!isError) return;

    // the Traceparent header is a W3C Trace Context
    const traceparentHeader = res.request.headers[&amp;#39;Traceparent&amp;#39;];

    // Add any other useful information
    const errorData = Object.assign(
      {
        url: res.url,
        status: res.status,
        error_code: res.error_code,
        traceparent: traceparentHeader &amp;amp;&amp;amp; traceparentHeader.toString(),
      },
      tags
    );
    this.logErrorDetails(errorData);
  }
}

// Set up the error handler to log errors to the console
const errorHandler = new ErrorHandler((error) =&amp;gt; {
  console.error(error);
});

/* Alternatively, you may log errors using a custom metric or any other option.
const errors = new CounterMetric(&amp;#39;errors&amp;#39;);
const errorHandler = new ErrorHandler((error) =&amp;gt; {errors.add(1, error);});
*/

// Basic example to demonstrate the error handler
export default function () {
  let res, checkStatus;

  res = http.get(&amp;#39;https://httpbin.org/status/200&amp;#39;);
  checkStatus = check(res, { &amp;#39;status is 200&amp;#39;: (res) =&amp;gt; res.status === 200 });
  errorHandler.logError(!checkStatus, res);

  res = http.get(&amp;#39;https://httpbin.org/status/300&amp;#39;);
  checkStatus = check(res, { &amp;#39;status is 200&amp;#39;: (res) =&amp;gt; res.status === 200 });
  errorHandler.logError(!checkStatus, res);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="error-handler">Error handler&lt;/h1>
&lt;p>When encountering errors from an application&amp;rsquo;s backend, gathering additional error information, such as error messages, tracing data, or request and response bodies, is often necessary. The initial suggestion is to leverage your observability solution to find these errors. However, capturing error details directly in k6 can also be useful for troubleshooting.&lt;/p></description></item><item><title>Tutorials</title><link>https://grafana.com/docs/k6/v2.3.x/examples/tutorials/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/examples/tutorials/</guid><content><![CDATA[&lt;h1 id=&#34;tutorials&#34;&gt;Tutorials&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/examples/get-started-with-k6/&#34;&gt;Get started with k6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/learning-js-through-load-testing/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;8 basic tasks to learn k6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/grafana/k6-learn&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;k6 Learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/load-testing-your-api-with-swagger-openapi-and-k6&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Swagger/OpenAPI integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/performance-monitoring-with-cron-and-k6&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Schedule k6 tests with cron&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/load-testing-graphql-with-k6&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Load test a GraphQL service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/javascript-typescript-compatibility-mode/&#34;&gt;Use TypeScript in k6 scripts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/k6-load-testing-debugging-using-a-web-proxy/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Debug using a Web Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/running-distributed-tests-on-k8s/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Distributed k6 tests on K8s&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k6.io/blog/extending-k6-with-xk6&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Create a k6 extension&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="tutorials">Tutorials&lt;/h1>
&lt;ul>
&lt;li>
&lt;a href="/docs/k6/v2.3.x/examples/get-started-with-k6/">Get started with k6&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/learning-js-through-load-testing/" target="_blank" rel="noopener noreferrer">8 basic tasks to learn k6&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/grafana/k6-learn" target="_blank" rel="noopener noreferrer">k6 Learn&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/load-testing-your-api-with-swagger-openapi-and-k6" target="_blank" rel="noopener noreferrer">Swagger/OpenAPI integration&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/performance-monitoring-with-cron-and-k6" target="_blank" rel="noopener noreferrer">Schedule k6 tests with cron&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/load-testing-graphql-with-k6" target="_blank" rel="noopener noreferrer">Load test a GraphQL service&lt;/a>&lt;/li>
&lt;li>
&lt;a href="/docs/k6/v2.3.x/using-k6/javascript-typescript-compatibility-mode/">Use TypeScript in k6 scripts&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/k6-load-testing-debugging-using-a-web-proxy/" target="_blank" rel="noopener noreferrer">Debug using a Web Proxy&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/running-distributed-tests-on-k8s/" target="_blank" rel="noopener noreferrer">Distributed k6 tests on K8s&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://k6.io/blog/extending-k6-with-xk6" target="_blank" rel="noopener noreferrer">Create a k6 extension&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>