Add 'data-testid' as HTML attribute for use with Playwright

Hello Inductivians!

Is there a way to add component properties as additional attributes to the component's HTML attributes?

When editing the "placeholder" property, in a TextArea, the value is passed to the corresponding HMTL tag in the Session Client. After trying to add a new .PROPS, "data-testid", the new attribute is not passed along. Other then putting a feature request, which I will probably do, is there a way to insert a custom attribute per component?

The main reason why I would like this feature is for a distinct way to look up components when using Playwright's .get_by_* functions for UI test automation. It looks like "data-component-path" is unique enough, but is a little clunky, and breakable if a component is moved.

image

The domId property should be added in the Meta area of any perspective component and it will add what you are looking for. For example, the Text Area on one of my pages is configured like this:

And when the page is loaded, the console shows the following when inspecting the Text Area:

All automation frameworks have the ability to target an ID and this should get you what you need.

Garth

2 Likes

That is exactly what I needed! Thanks Garth.

Just for anyone that might be trying to use Playwright, here is a code snippet that allowed me to select the TextArea container via the domId Garth instructed.

NOTES:

Using Maker Edition at home as a Proof of Concept, so I can take this to my big boy job's boss, and show him it works and get cooperate for software approval for Playwright. So the "page.get_by_text("AGREE & CLOSE").click()" probably wont apply to a fully licensed normal server.

And this of course does not work or intended to run in Jython 2.7 You will need to set up Playwright in your own Python 3 environment outside of Ignition, calling your project URL.

from playwright.sync_api import Playwright, sync_playwright, expect
import time


def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("http://localhost:8088/data/perspective/client/Playwright_Demo")
    page.get_by_text("AGREE & CLOSE").click()
    time.sleep(1)
    page.locator("[id='TR-0103a']").fill("Derek is cool.")
    time.sleep(5)
    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

A couple of notes that will help long-term:

  • From Playwright's docs, .fill() will wait for the element defined to be visible, enabled and editable, so the time.sleep(1) call might not be necessary.

  • The [id='TR-0103a'] locator is perfectly valid, but could be simplified as '#TR-0103a'. Even while perfectly valid, however, try to avoid non-descriptive id values long-term. When you hvae a failure and you're trying to find out why a component couldn't be found, an id value of "shipping_bay_dropdown" is far easier to visually locate than "TR-0103a".

1 Like

cmallonee, awesome Notes. Much appreciated.

1 Like