K6 Browser: Using .locator() on a found element gives error "Object has no member 'locator'"

In Playwright I could find an element, and then use that to find and use sub-elements, example: A row of cells some just text, some actionable such as a combo box with selectable options that I want to alter.

Trying to do something similar using k6 browser element throws an error.
k6 code snippet:

    let targetRow = await page.locator(`//div[@data-name="${name}"]`);
    await targetRow.locator(`//div[text()="${currentState}"]`).click();

Result Error:

ERRO[0005] Uncaught (in promise) TypeError: Object has no member ‘locator’

When I validate the targetRow element is correct by sending the inner text to the console, it shows all the correct values:

console.log("innerText: " + await targetRow.innerText());

Is this not supported? If it is supported in some manner, how would I go about this?

Any help would be greatly appreciated.

Hi @roadatlas,

Unfortunately k6 browser doesn’t implement locator.locator yet. The best way forward might be to work with page.$$ and iterate over the elements until you find the one that you’re looking for.

If you could share your test script pointing to a website that is public, i might be able to assist some more.

Best,
Ankur

That link says this:

Warning
Use locator-based page.locator(selector) instead.

And the page it sends me to doesn’t actually address the question because what I’m hoping for, eventually, is the ability to get a parent object such as a div element, and then itterate through it’s children.

k6 requires strict mode (locator returns exactly one element), which means when we’re migrating UI automation from Playwright to k6, we have to figure out what to put in the locator to tunnel down to exactly what we want and hope that it all works, even if we need to interact with multiple child elements in a list of elements.

Looking forward to locator.locator becoming a real thing.

Thanks!
Mike

Hi @roadatlas,

Warning
Use locator-based page.locator(selector) instead.

Correct, we do think working with the locator is the best way forward.

Since k6 browser doesn’t currently have locator.locator it might be worth trying $$. So something like:

    var cells = await page.$$(`//div[text()="${currentState}"]`);
    for (var i = 0; i < cells.length; i++) {
      if (await cells[i].innerText() == "something_you_expect") {
        await buttons[i].click();
        break;
      }
    }

I may have misunderstood your issue. If you could share your test script and public facing website that I can test on, then I might be able to align more with the issue your facing.

Best,
Ankur

1 Like

Thank you for that example, it’s actually very helpful, more so than k6 documentation page example here:

Example there:

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

  await page.goto('https://test.k6.io/browser.php');
  const text = await page.$$('#text1')[0];
  await text.type('hello world');
}

Bear in mind that I’m new to the k6 browser style of UI automation, it’s sufficiently different from what I’m used to that I’m relying to really good documentation to get me through the learning curve, and I’d be surprised if I was the only person who’s been trying to learn on the job.

Have a great weekend!
Mike Posluszny

1 Like

Glad I could help @roadatlas, and thank you for the feedback on the docs, i’ll incorporate this iterating example into the docs :pray:

1 Like