Playwright conversion to UI.Vision

OK, everything was great, but it seems a DOM root (tree) now hids all of the old objects and xpaths so everything stopped. I’ve tried several things. One of them was to find a tool that could interact with them… and I came across Playwight.

Below is what works. I’ve tried to JS this for UI.Vision - but I’m not smart enough. Anyone have any ideas. I read some posts on DOM here, but not enough for me to understand.

import { test, expect } from ‘@playwright/test’;
test(‘test’, async ({ page }) => {
await page.getByRole(‘combobox’, { name: ‘Enter symbol’ }).click();
await page.getByRole(‘combobox’, { name: ‘Enter symbol’ }).fill(‘AMD’);
await page.getByRole(‘combobox’, { name: ‘Enter symbol’ }).click();
await page.getByRole(‘button’, { name: ‘Trade’, exact: true }).click();
await page.getByLabel(‘Strategy Menu’).getByRole(‘option’, { name: ‘Stock/ETF’ }).click();
await page.locator(‘#order-control-action-0-select-id’).click();
await page.locator(‘#order-control-action-0-select-id’).selectOption(‘50’);
await page.locator(‘#order-control-order-type-0-select-id’).click();
await page.locator(‘#order-control-order-type-0-select-id’).selectOption(‘49’);
await page.getByRole(‘spinbutton’, { name: ‘Quantity’ }).click();
await page.getByRole(‘spinbutton’, { name: ‘Quantity’ }).fill(‘0.1001’);
await page.getByRole(‘button’, { name: ‘Review’ }).click();
});

What broke is not Ui.Vision but the page: the site now renders its trading form inside web components (shadow DOM). XPath and CSS in the command table stop at the shadow boundary, so the old locators find nothing. Playwright’s getByRole looks inside open shadow roots, and Ui.Vision has the same finders with the same names since version 10.0.203 (September 2026).

Your script needs almost no changes:

  • drop the await/test() wrapper,
  • add uiv. before page.,
  • and pass the found element to the action.

Click “New macro” (it opens the JavaScript editor), paste this, and press Play:

// Ui.Vision JavaScript macro (needs 10.0.203 or newer)
uiv.page.click(uiv.getByRole('combobox', {name: 'Enter symbol'}));
uiv.page.fill(uiv.getByRole('combobox', {name: 'Enter symbol'}), 'AMD');
uiv.page.click(uiv.getByRole('combobox', {name: 'Enter symbol'}));
uiv.page.click(uiv.getByRole('button', {name: 'Trade', exact: true}));
uiv.page.click(uiv.getByRole('option', {name: 'Stock/ETF'}));
uiv.page.selectOption(uiv.$('#order-control-action-0-select-id'), 'value=50');
uiv.page.selectOption(uiv.$('#order-control-order-type-0-select-id'), 'value=49');
uiv.page.click(uiv.getByRole('spinbutton', {name: 'Quantity'}));
uiv.page.fill(uiv.getByRole('spinbutton', {name: 'Quantity'}), '0.1001');
uiv.page.click(uiv.getByRole('button', {name: 'Review'}));

Three details:

  • No await: every uiv.* call waits for the page by itself before the next line runs.
  • Playwright’s selectOption('50') picks the option by its value. In Ui.Vision write 'value=50'; a bare string matches the visible option text instead.
  • getByLabel('Strategy Menu').getByRole('option', ...) narrows the search to the menu. Ui.Vision does not chain finders yet, so the line above searches the whole page for the option named Stock/ETF. If that name appears elsewhere, add exact: true or use uiv.getByText.

If a control is inside a closed shadow root, no DOM tool reaches it, Playwright included. Then XClickText or XClick with an image work, because they act on what is on screen.

:backhand_index_pointing_right:OR: You can paste your Playwright script into the Ui.Vision AI chat and ask for the Ui.Vision conversion; our AI can do it, it knows these finders. Bascially the result will be what I posted above.