Skip to content

Commit d16a334

Browse files
authored
feat(cypress-commands): add findToolbarButtonByText query (#6463)
1 parent 5c57bef commit d16a334

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

packages/cypress-commands/src/queries.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
interface FindToolbarButtonByTextOptions {
2+
queryShadowButton?: boolean;
3+
}
4+
15
declare global {
26
// eslint-disable-next-line @typescript-eslint/no-namespace
37
namespace Cypress {
@@ -23,7 +27,24 @@ declare global {
2327
* @example cy.get('[ui5-tab-container]').findUi5TabOpenPopoverButtonByText('Tab 1.1');
2428
* @param {string} text The text of the sub-tab that should be queried.
2529
*/
26-
findUi5TabOpenPopoverButtonByText(text: string, options?: Partial<ClickOptions>): Chainable<Element>;
30+
findUi5TabOpenPopoverButtonByText(text: string): Chainable<Element>;
31+
32+
/**
33+
* Returns the element that represents the `ui5-toolbar-button`.
34+
* When `options.queryShadowButton` is `true`, the internal `button` element is returned, otherwise the `ui5-button` element.
35+
*
36+
* __Note:__ This query can either be chained to a `ui5-toolbar` or not be chained at all.
37+
*
38+
* __Note:__ The `text` next needs to be unique in the respective scope.
39+
*
40+
* @example cy.findToolbarButtonByText("Button Text")
41+
* @example cy.get('[ui5-toolbar]').findToolbarButtonByText("Button Text")
42+
*
43+
* @param {string} text - The text of the button to search for. This text should be unique within the toolbar to ensure a single button is returned.
44+
* @param {FindToolbarButtonByTextOptions} [options] - An optional object containing configuration options for the query.
45+
* @param {boolean} [options.queryShadowButton=false] - If set to `true`, the internal `button` element will be returned instead of the `ui5-button` element.
46+
*/
47+
findToolbarButtonByText(text: string, options?: FindToolbarButtonByTextOptions): Chainable<Element>;
2748
// private
2849
/**
2950
* Returns the internal input element inside the shadow-root.
@@ -36,6 +57,41 @@ declare global {
3657
}
3758
}
3859

60+
Cypress.Commands.addQuery('findToolbarButtonByText', function (text, options) {
61+
return (subject) => {
62+
if (subject !== undefined && !subject?.[0]?.hasAttribute('ui5-toolbar')) {
63+
const err = `findToolbarButtonByText() needs to be chained to a \`ui5-toolbar\`, or not be chained at all.`;
64+
throw new TypeError(err);
65+
}
66+
const container = subject ? [subject[0]] : document.querySelectorAll('[ui5-toolbar]');
67+
68+
const toolbarBtns: HTMLElement[] = [];
69+
container.forEach((el) => {
70+
if (el) {
71+
const toolbarDom = el.getDomRef();
72+
const buttons = Cypress.$(toolbarDom).find('[ui5-button]');
73+
const matchingButtons = buttons.filter(function () {
74+
return Cypress.$(this).text() === text;
75+
});
76+
77+
toolbarBtns.push(...matchingButtons);
78+
}
79+
});
80+
81+
if (toolbarBtns.length > 1) {
82+
const err = `Multiple ui5-toolbar-button elements with the same text ("${text}") were found.`;
83+
throw new TypeError(err);
84+
}
85+
86+
let toolbarBtn = toolbarBtns[0];
87+
if (options?.queryShadowButton) {
88+
toolbarBtn = toolbarBtn.shadowRoot!.querySelector('button')!;
89+
}
90+
91+
return Cypress.$(toolbarBtn);
92+
};
93+
});
94+
3995
Cypress.Commands.addQuery('findShadowInput', function () {
4096
const getShadow = cy.now('shadow');
4197
const getInput = cy.now('find', 'input');

packages/cypress-commands/test/UI5WebComponentsChild.cy.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import {
1616
Switch,
1717
Tab,
1818
TabContainer,
19-
TextArea
19+
TextArea,
20+
Toolbar,
21+
ToolbarButton
2022
} from '@ui5/webcomponents-react';
2123

2224
describe('UI5 Web Components - Child Commands', () => {
@@ -260,4 +262,26 @@ describe('UI5 Web Components - Child Commands', () => {
260262
cy.wait(200);
261263
});
262264
});
265+
266+
it('findToolbarButtonByText', () => {
267+
cy.mount(
268+
<>
269+
<Toolbar>
270+
<ToolbarButton text="TBB1" />
271+
<ToolbarButton text="TBB2" />
272+
</Toolbar>
273+
<Toolbar>
274+
<ToolbarButton text="TBB3" />
275+
</Toolbar>
276+
<Toolbar>
277+
<ToolbarButton text="TBB4" style={{ display: 'none' }} />
278+
</Toolbar>
279+
</>
280+
);
281+
282+
cy.findToolbarButtonByText('TBB1').should('be.visible');
283+
cy.findToolbarButtonByText('TBB2').should('be.visible');
284+
cy.findToolbarButtonByText('TBB3').should('be.visible');
285+
cy.findToolbarButtonByText('TBB3').should('exist').not('be.visible');
286+
});
263287
});

0 commit comments

Comments
 (0)