Rayrun
← Back to Discord Forum

Custom Selector Engine

Looking to create my first custom selector engine. Im referencing these docs: https://playwright.dev/docs/extensibility#custom-selector-engines

My question is. How do i properly create a selector. I also have been referencing this as well. https://www.browserstack.com/guide/playwright-selectors

This is a snippet from the previously mentioned docs.

playwright.selectors.register('data-testid', {
create(root, target) {
return root.querySelector(`[data-testid="${target}"]`);
},
});
// Use your custom selector
await page.locator('data-testid=myTestId');```

I get an error when trying to create a selector. 


Above my test , i have this function.

```const rectSelectorEngine = () => ({
  // Returns the first element matching given selector in the root's subtree.
  query(root, selector) {
    return root.querySelector(selector);
  },

  // Returns all elements matching given selector in the root's subtree.
  queryAll(root, selector) {
    return Array.from(root.querySelectorAll(selector));
  },
});```


```const urls = await page.$$('div[class = "canvas sectionCanvas"]');```

I will want to use this as my selector.  This returns 4 rect elements on the DOM.


```await selectors.register("selector", rectSelectorEngine, {
      create(root, selector) {
        return page.$$('div[class = "canvas sectionCanvas"]');
      },
    });``` 

my create method throws an error.

This thread is trying to answer question "How do I properly create a custom selector engine using Playwright?"

3 replies

ohhh i think i need to speicify the selector in my rectSelectorEngine func

// Returns the first element matching given selector in the root's subtree.
  query(root, selector) {
    return root.querySelector('div[class = "canvas sectionCanvas"]');
  },

  // Returns all elements matching given selector in the root's subtree.
  queryAll(root, selector) {
    return Array.from(root.querySelectorAll('div[class = "canvas sectionCanvas"]'));
  },
});```

Maybe like this? Ill give it a shot and report back

it did not like my register name haha

Answer

Creating a Custom Selector Engine in Playwright

Creating a custom selector engine in Playwright involves a few steps.

Registering the Selector Engine

First, you need to register your custom selector engine using the selectors.register() method. This method requires a create function, a query function, and a queryAll function.

Here's an example of how to register a custom engine that queries elements based on their tag name:

import { selectors } from '@playwright/test';

const createTagNameEngine = () => ({
  query(root: Document | ShadowRoot | Element, selector: string) {
    return root.querySelector(selector);
  },
  queryAll(root: Document | ShadowRoot | Element, selector: string) {
    return Array.from(root.querySelectorAll(selector));
  },
});

await selectors.register('tag', createTagNameEngine);

Using the Custom Selector Engine

Once registered, you can use your custom selector engine by prefixing the selector with its name. For example:

const button = page.locator('tag=button');

You can also combine your custom selectors with built-in locators and use them in any methods that support selectors. For example:

await page.locator('tag=div').getByText('Click me').click();

And you can perform assertions on elements selected using your custom engine:

await expect(page.locator('tag=button')).toHaveCount(3);

Remember to register your selectors before creating any pages in Playwright. For more details, check out Mastering Playwright Test Automation: Your Comprehensive Cheat Sheet.

Related Discord Threads

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.