Does k6 browser support url matching patterns for thresholds?

Hey everyone,

Im currently trying to write some tests for web app within k6 experimental browser.
While I can create a threshold like this, that works just fine:

thresholds: {
‘webvital_largest_content_paint{url:www.example-url.com/somepage/someinneresource/page.html’ : [‘p(90) < 2500’],
},

Following threshold doesn’t seem to monitor trace:

thresholds: {
‘webvital_largest_content_paint{url:www.example-url.com/**’ : [‘p(90) < 2500’],
},

Is there some way to achieve this? It would be nice to be able to make some patterns for urls, like I log in to some certain page, but then id in the query string could be diffferent, so it would be more convenient to just use some general patterns like this.

Another thing is that k6 browser doesn’t seem to pick up urls for thresholds unless You use these urls in actions like await page.goto(url) or await page.reload(), are there any plans to maybe extend this thresholds measurments for redirects from page to page, without explicitly calling those page with page.goto or page.reload?

Best regards,
Artur

Hi @ArturS, welcome to the forum! :wave:

I think these are interesting points, let’s address them individually.

About the pattern matching on URL label for threshold. I think this can be an interesting feature, but this would most probably have to be supported “generically” in all metric labels.
This is more related with k6 core, so could you please write this specific part of the question in the k6 OSS forum? Or even create a Github issue for the feature request if you want. The k6 core team will address them from there.

As an alternative for your use case without requiring the pattern mathcing, we have this issue open in k6 browser which would allow labeling specific page.goto() actions, which could be used when defining the thresholds. Do you think this would fulfill your use case?

About thresholds only for the URLS used in page.goto() or page.reload(). This should not be the case. Web Vitals metrics should be measured on every loaded page. So for example, if you go to a site that returns a redirect to URL_X, there should be metrics associated for URL_X at the end of the test.
Are you experiencing different behavior? Could you provide us more details on this, or an example of a test that we can run?

Regards.

Hi,

I’m sorry to wake up this thread but I still can’t find a solution for this case. I’m trying to load an url (account overview) accessible from the main meny on the main overview page. Everytime I navigate to the url a new unique id is appended to the url (like this example: https://mydomain.se/account/overview/?id=jhkhkhj7676u786jy. This makes it impossible for me to measure the web vitals for the particular url https://mydomain.se/account/overview/ because when I define the threshold like this:

'browser_web_vital_inp{url:https://mydomain.se/account/overview/}': \['p(90) < 100'\],

I get only zeros for the web vitals of https://mydomain.se/account/overview/

Have you come up with a solution to this since the post was created back in 2023?

Thank you very much for some feedback.

Best regards

lightlore

Hi @Lightlore,

I believe this is now possible. I played around with page.on('metric') which I think resulted in what you’re asking for. What needs to happen is that the dynamic (high cardinality) URLs need to be grouped with a new tag name.

In the example below, I am navigating to https://quickpizza.grafana.com/?q=abc123 and https://quickpizza.grafana.com/?q=def456. The page.on event handler matches on the URLs with the regexp /^https:\/\/quickpizza\.grafana\.com\/\?q=[0-9a-z]+$/. When a match is found the url metric is retagged to test (both the name and url metric fields are replaced). Now i can define a threshold with the name of the new tag test like so 'browser_web_vital_fcp{name:test}': ['p(90) < 2000'].

Here’s my test script that you should be able to run:

import { browser } from 'k6/browser';

export const options = {
  scenarios: {
    ui: {
      executor: 'shared-iterations',
      options: {
        browser: {
            type: 'chromium',
        },
      },
    },
  },
  thresholds: {
    'browser_web_vital_fcp{name:test}': ['p(90) < 2000'],
  },
}

export default async function() {
  const page = await browser.newPage();

  page.on('metric', (metric) => {
    metric.tag({
      name:'test',
      matches: [
        {url: /^https:\/\/quickpizza\.grafana\.com\/\?q=[0-9a-z]+$/},
      ]
    });
  });

  try {
    await page.goto('https://quickpizza.grafana.com/?q=abc123');
    await page.goto('https://quickpizza.grafana.com/?q=def456');
  } finally {
    await page.close();
  }
}

The output for me is:

  █ THRESHOLDS 

    browser_web_vital_fcp{name:test}
    ✓ 'p(90) < 2000' p(90)=512ms

    ...

    WEB_VITALS
    browser_web_vital_fcp.......: avg=512ms    min=512ms    med=512ms    max=512ms    p(90)=512ms    p(95)=512ms   
      { name:test }.............: avg=512ms    min=512ms    med=512ms    max=512ms    p(90)=512ms    p(95)=512ms   
    browser_web_vital_ttfb......: avg=354.4ms  min=354.4ms  med=354.4ms  max=354.4ms  p(90)=354.4ms  p(95)=354.4ms

Hope this helps!
Ankur