diff --git a/docs/modules/plugins/pages/plugin-web-app-playwright.adoc b/docs/modules/plugins/pages/plugin-web-app-playwright.adoc index cacfcfa347..9bda82dbe2 100644 --- a/docs/modules/plugins/pages/plugin-web-app-playwright.adoc +++ b/docs/modules/plugins/pages/plugin-web-app-playwright.adoc @@ -112,6 +112,39 @@ By. prefix is optional. |Locates elements whose class name matches the specified search value. This locator is translated to `css(.)` locator. |className(bold) +|`linkText` +|Locates elements whose text of the link matches the specified search value. +|linkText(Google) + +|`linkUrl` +|Locates elements whose `href` attribute matches the specified search value. This locator is translated to `css([href=''])` locator. +|linkUrl(/faq) + +|`linkUrlPart` +|Locates elements whose part of `href` attribute matches the specified search value. This locator is translated to `css([href*=''])` locator. +|linkUrlPart(faq) + +|`imageSrc` +|Locates elements whose `src` attribute matches the specified search value. This locator is translated to `css(img[src=''])` locator. +|imgSrc(/images/kote.png) + +|`imageSrcPart` +|Locates elements whose part of `src` attribute matches the specified search value. This locator is translated to `css(img[src*=''])` locator. +|imgSrcPart(kote.png) + +|`fieldName` +|Locate elements that are either input or textarea and their text or any attribute value matches the specified search value +|fieldName(editor) + +|`radioButton` +|Locate elements that are input with @type="radio" and their label text value matches the specified searh value +|radioButton(One) + +|`elementName` +|Locate elements where any attribute or text value the specified search value. This locator is translated to `xpath(.//\*[@*='' or text()=''])` +locator. +|elementName(OK) + |=== === Visibility types diff --git a/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorType.java b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorType.java index a6f01ed434..cdd8423a15 100644 --- a/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorType.java +++ b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorType.java @@ -39,7 +39,7 @@ public PlaywrightLocator createLocator(String value) @Override public PlaywrightLocator createLocator(String value) { - return new PlaywrightLocator("xpath", value); + return createXpathLocator(value); } }, TAG_NAME @@ -57,6 +57,74 @@ public PlaywrightLocator createLocator(String value) { return createCssLocator("." + value); } + }, + LINK_TEXT + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createXpathLocator(".//a[text()='%1$s' or @*='%1$s' or *='%1$s']", value); + } + }, + LINK_URL + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createCssLocator("a[href='%s']", value); + } + }, + LINK_URL_PART + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createCssLocator("a[href*='%s']", value); + } + }, + IMAGE_SRC + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createCssLocator("img[src='%s']", value); + } + }, + IMAGE_SRC_PART + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createCssLocator("img[src*='%s']", value); + } + }, + FIELD_NAME + { + @Override + public PlaywrightLocator createLocator(String value) + { + // due to firefox bug, we can't use name() and must use local-name() + // as workaround 'body' represents CKE editor + return createXpathLocator(".//*[(local-name() = 'input' or local-name() = 'textarea' or " + + "local-name()='body') and ((@* | text())='%1$s' or @id=(//label[text() = '%1$s']/@for))]", value); + } + }, + RADIO_BUTTON + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createXpathLocator(".//input[@type='radio' and ((@* | text())=%1$s or " + + "@id=(//label[text() = '%1$s']/@for))]", value); + } + }, + ELEMENT_NAME + { + @Override + public PlaywrightLocator createLocator(String value) + { + return createXpathLocator(".//*[@*='%1$s' or text()='%1$s']", value); + } }; public abstract PlaywrightLocator createLocator(String value); @@ -65,4 +133,14 @@ private static PlaywrightLocator createCssLocator(String value) { return new PlaywrightLocator("css", value); } + + private static PlaywrightLocator createCssLocator(String locatorPattern, String value) + { + return createCssLocator(String.format(locatorPattern, value)); + } + + private static PlaywrightLocator createXpathLocator(String locatorPattern, Object... args) + { + return new PlaywrightLocator("xpath", String.format(locatorPattern, args)); + } } diff --git a/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorTypeTests.java b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorTypeTests.java index 56cc39cfc7..a62447b2bc 100644 --- a/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorTypeTests.java +++ b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/locator/PlaywrightLocatorTypeTests.java @@ -43,7 +43,7 @@ void shouldCreateLocatorByClassName() void shouldCreateLocatorByXpath() { var xpath = "//div"; - assertEquals(new PlaywrightLocator("xpath", xpath), PlaywrightLocatorType.XPATH.createLocator(xpath)); + assertEquals(createXpathLocator(xpath), PlaywrightLocatorType.XPATH.createLocator(xpath)); } @Test @@ -60,6 +60,75 @@ void shouldCreateLocatorByTagName() assertEquals(createCssLocator(tagName), PlaywrightLocatorType.TAG_NAME.createLocator(tagName)); } + @Test + void shouldCreateLocatorByLinkText() + { + var expectedXpath = ".//a[text()='linkText' or @*='linkText' or *='linkText']"; + assertEquals(createXpathLocator(expectedXpath), PlaywrightLocatorType.LINK_TEXT.createLocator("linkText")); + } + + @Test + void shouldCreateLocatorByLinkUrl() + { + var linkUrl = "linkUrl"; + assertEquals(createCssLocator("a[href='linkUrl']"), PlaywrightLocatorType.LINK_URL.createLocator(linkUrl)); + } + + @Test + void shouldCreateLocatorByLinkUrlPart() + { + var linkUrlPart = "linkUrlPart"; + assertEquals(createCssLocator("a[href*='linkUrlPart']"), + PlaywrightLocatorType.LINK_URL_PART.createLocator(linkUrlPart)); + } + + @Test + void shouldCreateLocatorByImageSrc() + { + var imageSrc = "/image/src"; + assertEquals(createCssLocator("img[src='/image/src']"), + PlaywrightLocatorType.IMAGE_SRC.createLocator(imageSrc)); + } + + @Test + void shouldCreateLocatorByImageSrcPart() + { + var imageSrcPart = "src"; + assertEquals(createCssLocator("img[src*='src']"), + PlaywrightLocatorType.IMAGE_SRC_PART.createLocator(imageSrcPart)); + } + + @Test + void shouldCreateLocatorByElementName() + { + var elementName = "elementName"; + assertEquals(createXpathLocator(".//*[@*='elementName' or text()='elementName']"), + PlaywrightLocatorType.ELEMENT_NAME.createLocator(elementName)); + } + + @Test + void shouldCreateLocatorByFieldName() + { + var fieldName = "fieldName"; + var expectedXpath = ".//*[(local-name() = 'input' or local-name() = 'textarea' or local-name()='body') and " + + "((@* | text())='fieldName' or @id=(//label[text() = 'fieldName']/@for))]"; + assertEquals(createXpathLocator(expectedXpath), PlaywrightLocatorType.FIELD_NAME.createLocator(fieldName)); + } + + @Test + void shouldCreateLocatorByRadioButton() + { + var radioButton = "radioButton"; + var expectedXpath = ".//input[@type='radio' and ((@* | text())=radioButton or " + + "@id=(//label[text() = 'radioButton']/@for))]"; + assertEquals(createXpathLocator(expectedXpath), PlaywrightLocatorType.RADIO_BUTTON.createLocator(radioButton)); + } + + private PlaywrightLocator createXpathLocator(String value) + { + return new PlaywrightLocator("xpath", value); + } + private PlaywrightLocator createCssLocator(String value) { return new PlaywrightLocator("css", value);