Skip to content

Commit

Permalink
Merge branch 'master' into issue_1350
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaepam authored Jul 20, 2023
2 parents 10e2e02 + b30a9c3 commit ed9763b
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 21 deletions.
65 changes: 65 additions & 0 deletions src/__tests__/locators/utils/__mocks__/locatorEscaped.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
export const locatorMocks = [
{
input:
'"//*[@data-nav-tracking-menu-navigate-down=\'[{"method":"submitEvent","dataContainer":{"nav_MenuAction":"down","nav_MenuRank":2,"nav_MenuLevel":1,"nav_MenuTitle":"Damen-Mode","nav_MenuType":"curated","nav_GlobalNavigation":"damen-mode"}}]\']"',
output:
'"//*[@data-nav-tracking-menu-navigate-down=\\\'[{\\\\"method\\\\":\\\\"submitEvent\\\\",\\\\"dataContainer\\\\":{\\\\"nav_MenuAction\\\\":\\\\"down\\\\",\\\\"nav_MenuRank\\\\":2,\\\\"nav_MenuLevel\\\\":1,\\\\"nav_MenuTitle\\\\":\\\\"Damen-Mode\\\\",\\\\"nav_MenuType\\\\":\\\\"curated\\\\",\\\\"nav_GlobalNavigation\\\\":\\\\"damen-mode\\\\"}}]\\\']"',
},
{
input:
'"[data-nav-tracking-menu-navigate-down=\'[{"method":"submitEvent","dataContainer":{"nav_MenuAction":"down","nav_MenuRank":2,"nav_MenuLevel":1,"nav_MenuTitle":"Damen-Mode","nav_MenuType":"curated","nav_GlobalNavigation":"damen-mode"}}]\']"',
output:
'"[data-nav-tracking-menu-navigate-down=\\\'[{\\\\"method\\\\":\\\\"submitEvent\\\\",\\\\"dataContainer\\\\":{\\\\"nav_MenuAction\\\\":\\\\"down\\\\",\\\\"nav_MenuRank\\\\":2,\\\\"nav_MenuLevel\\\\":1,\\\\"nav_MenuTitle\\\\":\\\\"Damen-Mode\\\\",\\\\"nav_MenuType\\\\":\\\\"curated\\\\",\\\\"nav_GlobalNavigation\\\\":\\\\"damen-mode\\\\"}}]\\\']"',
},
{
input:
'@FindBy(xpath = "//*[@data-nav-tracking-menu-navigate-down=\'[{"method":"submitEvent","dataContainer":{"nav_MenuAction":"down","nav_MenuRank":2,"nav_MenuLevel":1,"nav_MenuTitle":"Damen-Mode","nav_MenuType":"curated","nav_GlobalNavigation":"damen-mode"}}]\']")',
output:
'@FindBy(xpath = "//*[@data-nav-tracking-menu-navigate-down=\\\'[{\\\\"method\\\\":\\\\"submitEvent\\\\",\\\\"dataContainer\\\\":{\\\\"nav_MenuAction\\\\":\\\\"down\\\\",\\\\"nav_MenuRank\\\\":2,\\\\"nav_MenuLevel\\\\":1,\\\\"nav_MenuTitle\\\\":\\\\"Damen-Mode\\\\",\\\\"nav_MenuType\\\\":\\\\"curated\\\\",\\\\"nav_GlobalNavigation\\\\":\\\\"damen-mode\\\\"}}]\\\']")',
},
{
input:
'@FindBy(css = "[data-nav-tracking-menu-navigate-down=\'[{"method":"submitEvent","dataContainer":{"nav_MenuAction":"down","nav_MenuRank":2,"nav_MenuLevel":1,"nav_MenuTitle":"Damen-Mode","nav_MenuType":"curated","nav_GlobalNavigation":"damen-mode"}}]\']")',
output:
'@FindBy(css = "[data-nav-tracking-menu-navigate-down=\\\'[{\\\\"method\\\\":\\\\"submitEvent\\\\",\\\\"dataContainer\\\\":{\\\\"nav_MenuAction\\\\":\\\\"down\\\\",\\\\"nav_MenuRank\\\\":2,\\\\"nav_MenuLevel\\\\":1,\\\\"nav_MenuTitle\\\\":\\\\"Damen-Mode\\\\",\\\\"nav_MenuType\\\\":\\\\"curated\\\\",\\\\"nav_GlobalNavigation\\\\":\\\\"damen-mode\\\\"}}]\\\']")',
},
{
input:
'@UI("//*[@data-nav-tracking-menu-navigate-down=\'[{"method":"submitEvent","dataContainer":{"nav_MenuAction":"down","nav_MenuRank":2,"nav_MenuLevel":1,"nav_MenuTitle":"Damen-Mode","nav_MenuType":"curated","nav_GlobalNavigation":"damen-mode"}}]\']")',
output:
'@UI("//*[@data-nav-tracking-menu-navigate-down=\\\'[{\\\\"method\\\\":\\\\"submitEvent\\\\",\\\\"dataContainer\\\\":{\\\\"nav_MenuAction\\\\":\\\\"down\\\\",\\\\"nav_MenuRank\\\\":2,\\\\"nav_MenuLevel\\\\":1,\\\\"nav_MenuTitle\\\\":\\\\"Damen-Mode\\\\",\\\\"nav_MenuType\\\\":\\\\"curated\\\\",\\\\"nav_GlobalNavigation\\\\":\\\\"damen-mode\\\\"}}]\\\']")',
},
{
input:
'@UI("[data-nav-tracking-menu-navigate-down=\'[{"method":"submitEvent","dataContainer":{"nav_MenuAction":"down","nav_MenuRank":2,"nav_MenuLevel":1,"nav_MenuTitle":"Damen-Mode","nav_MenuType":"curated","nav_GlobalNavigation":"damen-mode"}}]\']")',
output:
'@UI("[data-nav-tracking-menu-navigate-down=\\\'[{\\\\"method\\\\":\\\\"submitEvent\\\\",\\\\"dataContainer\\\\":{\\\\"nav_MenuAction\\\\":\\\\"down\\\\",\\\\"nav_MenuRank\\\\":2,\\\\"nav_MenuLevel\\\\":1,\\\\"nav_MenuTitle\\\\":\\\\"Damen-Mode\\\\",\\\\"nav_MenuType\\\\":\\\\"curated\\\\",\\\\"nav_GlobalNavigation\\\\":\\\\"damen-mode\\\\"}}]\\\']")',
},

{
input: "\"//*[contains(text(), 'Jetzt: GenialCard + 25€-Gutschein!')]\"",
output: "\"//*[contains(text(), \\'Jetzt: GenialCard + 25€-Gutschein!\\')]\"",
},
{
input: '"#\\35 8776894140b02029425a3e2 [style="display\\:\\ inline\\;"]"',
output: '"#\\\\\\\\35 8776894140b02029425a3e2 [style=\\\\"display\\\\\\\\:\\\\\\\\ inline\\\\\\\\;\\\\"]"',
},
{
input: '"[jsname="NNJLud"]:nth-child(3) [role="menuitem"]"',
output: '"[jsname=\\\\"NNJLud\\\\"]:nth-child(3) [role=\\\\"menuitem\\\\"]"',
},
{
input: "\"//*[@data-ved='0ahUKEwjs1sqi4JqAAxUUSkEAHfQZDjgQ4dUDCAk']\"",
output: "\"//*[@data-ved=\\'0ahUKEwjs1sqi4JqAAxUUSkEAHfQZDjgQ4dUDCAk\\']\"",
},
{
input: '".tm-navigation-filters__option:nth-child(6) > [tabindex="-\\31 "]"',
output: '".tm-navigation-filters__option:nth-child(6) > [tabindex=\\\\"-\\\\\\\\31 \\\\"]"',
},
{
input:
'@UI("#\\37 49046 .tm-article-snippet__hubs-item:nth-child(2) > .tm-article-snippet__hubs-item-link")\npublic Label cLabel1;',
output:
'@UI("#\\\\\\\\37 49046 .tm-article-snippet__hubs-item:nth-child(2) > .tm-article-snippet__hubs-item-link")\\npublic Label cLabel1;',
},
];
8 changes: 8 additions & 0 deletions src/__tests__/locators/utils/escapeLocator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { locatorMocks } from "./__mocks__/locatorEscaped.mock";
import { escapeLocator } from "../../../common/utils/copyToClipboard";

test("escape symbols in locator", () => {
locatorMocks.forEach((locator) => {
expect(escapeLocator(locator.input)).toBe(locator.output);
});
});
2 changes: 1 addition & 1 deletion src/common/components/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Tooltip } from "antd";
import { Copy } from "phosphor-react";
import React, { useState } from "react";
import { copyToClipboard } from "../utils/helpers";
import { copyToClipboard } from "../utils/copyToClipboard";
import { CopyTitle } from "../types/common";

interface Props {
Expand Down
38 changes: 38 additions & 0 deletions src/common/utils/copyToClipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export const escapeLocator = (locator: string) => {
let transformedText = locator.replace(/[\\'\n]/g, (match: string) => {
switch (match) {
case "\\":
return "\\\\\\\\";
case "'":
return "\\'";
case "\n":
return "\\n";
default:
return match;
}
});
const lastDoubleQuote = transformedText.lastIndexOf('"');
const firstDoubleQuote = transformedText.indexOf('"');
const beforeFirstDoubleQuote = transformedText.slice(0, firstDoubleQuote + 1);
const afterLastDoubleQuote = transformedText.slice(lastDoubleQuote);
let insideOfDoubleQuotes = transformedText.slice(firstDoubleQuote + 1, lastDoubleQuote);

if (insideOfDoubleQuotes.includes('"')) {
insideOfDoubleQuotes = insideOfDoubleQuotes.replace(/"/g, '\\\\"');
transformedText = beforeFirstDoubleQuote + insideOfDoubleQuotes + afterLastDoubleQuote;
}

return transformedText;
};

export const copyToClipboard = (value: string | string[]) => {
let transformedText;

if (typeof value === "string") {
transformedText = escapeLocator(value);
} else {
transformedText = value.map((el: string) => escapeLocator(el)).join("\\n\\n");
}

chrome.devtools.inspectedWindow.eval(`copy('${transformedText}')`);
};
12 changes: 0 additions & 12 deletions src/common/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ export const floatToPercent = (value: number) => {
return Math.trunc(value * 100);
};

export const copyToClipboard = (text: string) => {
// "\\\\3" - needed to get "\3" in 'eval()'
const transformedText = text
.replace(/'/g, "\\'")
.replace(/\n/g, "\\n")
.replace(/#\\3/g, "#\\\\3")
.replace(/=\\'\\3/g, "=\\'\\\\3") // two different cases for \\3 to avoid affecting something else...
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"');
chrome.devtools.inspectedWindow.eval(`copy('${transformedText}')`);
};

export const getLocatorString = (locator: LocatorValue, type: ElementLibrary | ElementClass, name: string): string =>
`@UI("${locator.output}")\npublic ${type} ${name};`;

Expand Down
2 changes: 1 addition & 1 deletion src/features/locators/components/LocatorCopyButton.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Tooltip } from "antd";
import { CopySimple } from "phosphor-react";
import React, { useState } from "react";
import { copyToClipboard, getLocatorString } from "../../../common/utils/helpers";
import { copyToClipboard, getLocatorString } from "../../../common/utils/copyToClipboard";
import { CopyTitle } from "../../../common/types/common";

export const LocatorCopyButton = ({ element }) => {
Expand Down
3 changes: 2 additions & 1 deletion src/features/locators/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import {
ElementId,
JDNHash,
} from "../types/locator.types";
import { copyToClipboard, getLocatorString, getElementFullXpath } from "../../../common/utils/helpers";
import { getLocatorString, getElementFullXpath } from "../../../common/utils/helpers";
import { LocatorOption } from "./constants";
import { LocatorType } from "../../../common/types/common";
import { isStringContainsNumbers } from "../../../common/utils/helpers";
import { FormInstance } from "antd/es/form/Form";
import { copyToClipboard } from "../../../common/utils/copyToClipboard";

export const getLocatorWithJDIAnnotation = (locator: string): string => `@UI("${locator}")`;

Expand Down
5 changes: 3 additions & 2 deletions src/features/pageObjects/components/PageObjCopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { FC, MouseEvent, useState } from "react";

import { Button, Tooltip } from "antd";
import { copyToClipboard, getLocatorString } from "../../../common/utils/helpers";
import { getLocatorString } from "../../../common/utils/helpers";
import { CopySimple } from "phosphor-react";
import { Locator } from "../../locators/types/locator.types";
import { CopyTitle } from "../../../common/types/common";
import { copyToClipboard } from "../../../common/utils/copyToClipboard";

interface Props {
elements: Locator[];
Expand All @@ -14,7 +15,7 @@ export const PageObjCopyButton: FC<Props> = ({ elements }) => {
const [copyTooltipTitle, setTooltipTitle] = useState(CopyTitle.Copy);

const getPageObjectForCopying = (locators: Locator[]) => {
return locators.map(({ locator, type, name }) => getLocatorString(locator, type, name)).join("\n\n");
return locators.map(({ locator, type, name }) => getLocatorString(locator, type, name));
};

const handleCopy = (e: MouseEvent<HTMLElement>) => {
Expand Down
7 changes: 3 additions & 4 deletions src/pageServices/contentScripts/generationData.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,14 @@ export const getGenerationAttributes = () => {

const isSelectorByGeneratorString = typeof selectorByGenerator === "string";
const isSelectorByFinderString = typeof selectorByFinder === "string";
const transformSelector = (selector) => selector.replace(/"/g, "'");

if (isSelectorByGeneratorString && isSelectorByFinderString) {
const selector = selectorByGenerator.length < selectorByFinder.length ? selectorByGenerator : selectorByFinder;
return transformSelector(selector);
return selector;
} else if (!isSelectorByFinderString && isSelectorByGeneratorString) {
return transformSelector(selectorByGenerator);
return selectorByGenerator;
} else if (!isSelectorByGeneratorString && isSelectorByFinderString) {
return transformSelector(selectorByFinder);
return selectorByFinder;
} else {
return "CSS selector generation was failed";
}
Expand Down

0 comments on commit ed9763b

Please sign in to comment.