Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions playwright/fixtures/ui5-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ function escapeAttributeValue(value: string): string {
export class UI5WCHelpers {
constructor(protected page: Page) {}

/**
* Clicks a UI5 custom element via its shadow-inner root node
* (`getDomRef()`), with a fallback to the host element.
*
* @param locator Locator of the UI5 custom element to click.
*/
private async clickViaDomRef(locator: Locator): Promise<void> {
await locator.evaluate((element: HTMLElement) => {
const host = element as HTMLElement & { getDomRef?: () => HTMLElement | null };
(host.getDomRef?.() ?? host).click();
});
}

/**
* Types a value into a UI5 input component.
* Works with Input, ComboBox, MultiComboBox, MultiInput, DatePicker, etc.
Expand Down Expand Up @@ -146,6 +159,37 @@ export class UI5WCHelpers {
findTabPopoverButtonByText(tabContainer: Locator, text: string): Locator {
return tabContainer.locator('[role="tab"]').filter({ hasText: text }).locator('[ui5-button]');
}

/**
* Selects a menu item inside an open Menu by its rendered text.
* Must be called after the menu is open.
*
* @example
* const menu = page.getByTestId('my-menu');
* await ui5wc.selectMenuItemByText(menu, 'Save');
*/
async selectMenuItemByText(menu: Locator, text: string): Promise<void> {
await expect(menu).toHaveAttribute('open', '');
const menuItem = menu.locator(`[ui5-menu-item][text="${escapeAttributeValue(text)}"]`).first();
await this.clickViaDomRef(menuItem);
}

/**
* Expands a UI5 TreeItem by clicking its toggle icon.
*
* @example
* await ui5wc.expandTreeItem(page.getByTestId('my-tree-item'));
*/
async expandTreeItem(treeItem: Locator): Promise<void> {
await expect(treeItem).toBeVisible();
await treeItem.evaluate((element: HTMLElement) => {
const icon = element.shadowRoot?.querySelector('[part="toggle-icon"]') as HTMLElement | null;
if (!icon) {
throw new Error('Toggle icon not found in shadow root of tree item');
}
icon.click();
});
}
}

export const test = base.extend<UI5WCFixtures>({
Expand Down
38 changes: 38 additions & 0 deletions playwright/test/UI5Fixtures.gallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ComboBox } from '@ui5/webcomponents-react/ComboBox';
import { ComboBoxItem } from '@ui5/webcomponents-react/ComboBoxItem';
import { Dialog } from '@ui5/webcomponents-react/Dialog';
import { Input } from '@ui5/webcomponents-react/Input';
import { Menu } from '@ui5/webcomponents-react/Menu';
import { MenuItem } from '@ui5/webcomponents-react/MenuItem';
import { MultiComboBox } from '@ui5/webcomponents-react/MultiComboBox';
import { MultiComboBoxItem } from '@ui5/webcomponents-react/MultiComboBoxItem';
import { MultiInput } from '@ui5/webcomponents-react/MultiInput';
Expand All @@ -12,6 +14,8 @@ import { SuggestionItem } from '@ui5/webcomponents-react/SuggestionItem';
import { Tab } from '@ui5/webcomponents-react/Tab';
import { TabContainer } from '@ui5/webcomponents-react/TabContainer';
import { TextArea } from '@ui5/webcomponents-react/TextArea';
import { Tree } from '@ui5/webcomponents-react/Tree';
import { TreeItem } from '@ui5/webcomponents-react/TreeItem';
import { useState } from 'react';

export const InputTestComp = () => {
Expand Down Expand Up @@ -160,3 +164,37 @@ export const MultiInputWithSuggestionsTestComp = () => {
</MultiInput>
);
};

export const MenuTestComp = () => {
const [open, setOpen] = useState(false);
const [clickedItem, setClickedItem] = useState('');
return (
<>
<Button id="menu-opener" data-testid="menu-opener" onClick={() => setOpen(true)}>
Open Menu
</Button>
<Menu
data-testid="test-menu"
open={open}
opener="menu-opener"
onClose={() => setOpen(false)}
onItemClick={(e) => setClickedItem(e.detail.item.getAttribute('text') || '')}
>
<MenuItem text="New" />
<MenuItem text="Edit" />
<MenuItem text="Delete" />
</Menu>
<span data-testid="menu-clicked-item">{clickedItem}</span>
</>
);
};

export const TreeTestComp = () => {
return (
<Tree data-testid="test-tree">
<TreeItem data-testid="test-tree-parent" text="Parent">
<TreeItem data-testid="test-tree-child" text="Child" />
</TreeItem>
</Tree>
);
};
21 changes: 21 additions & 0 deletions playwright/test/ui5-fixtures.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ test.describe('UI5 Web Components Fixtures', () => {
await expect(page.getByTestId('multicombobox-values')).toHaveText('Green');
});

test('selectMenuItemByText - selects Menu item', async ({ mount, page, ui5wc }) => {
await mount('test/UI5Fixtures/MenuTestComp');

await page.getByTestId('menu-opener').click();
await ui5wc.selectMenuItemByText(page.getByTestId('test-menu'), 'Delete');

await expect(page.getByTestId('menu-clicked-item')).toHaveText('Delete');
});

test('findTabByText - finds and clicks tab', async ({ mount, page, ui5wc }) => {
await mount('test/UI5Fixtures/TabContainerTestComp');

Expand Down Expand Up @@ -161,4 +170,16 @@ test.describe('UI5 Web Components Fixtures', () => {

await expect(multiInput.locator('[text="Suggestion X"]')).toBeVisible();
});

test('expandTreeItem - expands a tree item, revealing its child', async ({ mount, page, ui5wc }) => {
await mount('test/UI5Fixtures/TreeTestComp');

const parent = page.getByTestId('test-tree-parent');
const child = page.getByTestId('test-tree-child');
await expect(child).toBeHidden();

await ui5wc.expandTreeItem(parent);

await expect(child).toBeVisible();
});
});
Loading