diff --git a/src/components/utils/__tests__/xpath.test.tsx b/src/components/utils/__tests__/xpath.test.tsx
index 4eeb38696..d17b2656f 100644
--- a/src/components/utils/__tests__/xpath.test.tsx
+++ b/src/components/utils/__tests__/xpath.test.tsx
@@ -313,5 +313,51 @@ describe('getXpath', () => {
expect(xpath).toBe(rootBuilder.append({className: 'class__div'}).xpath);
expect(hash).toMatchInlineSnapshot(`"bf5138ce0f335973b588b4c3029e1335"`);
});
+
+ it('should remove id if it was converted to undefined', () => {
+ const onClick = jest.fn();
+ render(
+
,
+ );
+ screen.getByText(clickText).click();
+
+ const {xpath, hash} = getXpath(onClick.mock.calls[0][0], {
+ idConverter: (id) => (id.startsWith('remove') ? undefined : id),
+ });
+ expect(xpath).toBe(
+ rootBuilder.append().append({id: 'keep-this'}).append({className: 'target class-3'})
+ .xpath,
+ );
+ expect(hash).toMatchInlineSnapshot(`"21df5cf9017ae106f30a9a6608a9cb4a"`);
+ });
+
+ it('should convert some ids', () => {
+ const onClick = jest.fn();
+ render(
+ ,
+ );
+ screen.getByText(clickText).click();
+
+ const {xpath, hash} = getXpath(onClick.mock.calls[0][0], {
+ idConverter: (id) => id.replace('convert', 'keep'),
+ });
+ expect(xpath).toBe(
+ rootBuilder.append({id: 'keep-too'}).append({id: 'keep-this'}).append({id: 'keep'})
+ .xpath,
+ );
+ expect(hash).toMatchInlineSnapshot(`"2ac575742aa22271a17b4e1efb375330"`);
+ });
});
});
diff --git a/src/components/utils/xpath.ts b/src/components/utils/xpath.ts
index 2bc586843..4b8ff4c15 100644
--- a/src/components/utils/xpath.ts
+++ b/src/components/utils/xpath.ts
@@ -12,9 +12,13 @@ export type XpathClassConverter = (
strClass: string,
) => ElementClass | undefined;
+export type XpathIdConverter = (id: string) => string | undefined;
+
export interface XpathOptions {
/** Function for converting and filtering classes */
classConverter?: XpathClassConverter;
+ /** Function for converting and filtering ids */
+ idConverter?: XpathIdConverter;
/** Flag for managing replaces from tag[@class='...'] to tag[@id='...'] if id is exist */
withoutId?: boolean;
}
@@ -39,8 +43,10 @@ function getXpathByNode(node: Node | null, options: InternalXpathOptions): strin
const tag = node.tagName.toLowerCase();
let token = `/${tag}`;
- if (node.id && !options.withoutId) {
- token += `[@id='${node.id}']`;
+
+ const convertedId = node.id && !options.withoutId ? options.idConverter(node.id) : undefined;
+ if (convertedId) {
+ token += `[@id='${convertedId}']`;
} else {
const classes: string[] = [];
node.classList.forEach((className) => {
@@ -59,6 +65,7 @@ function getXpathByNode(node: Node | null, options: InternalXpathOptions): strin
const defaultXpathOptions: InternalXpathOptions = {
classConverter: (arg) => arg,
+ idConverter: (arg) => arg,
withoutId: false,
};