All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.serenitybdd.screenplay.ui.LocatorStrategies Maven / Gradle / Ivy

There is a newer version: 4.2.8
Show newest version
package net.serenitybdd.screenplay.ui;

import net.serenitybdd.core.pages.WebElementFacade;
import net.serenitybdd.core.pages.WebElementFacadeImpl;
import net.serenitybdd.core.selectors.Selectors;
import net.serenitybdd.screenplay.targets.Target;
import org.openqa.selenium.By;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class LocatorStrategies {

    public static Function> fieldWithLabel(String labelText) {
        return searchContext -> {
            // Find the label
            List matchingLabelsWithForAttribute = searchContext.findElements(By.xpath(labelsWithText(labelText)));
            if (matchingLabelsWithForAttribute.isEmpty()) {
                return new ArrayList<>();
            }
            // Let's see if the 'for' attribute has been specified
            String fieldId = matchingLabelsWithForAttribute.get(0).getAttribute("for");
            // If there is no for attribute, click on the label itself
            if ((fieldId == null) || fieldId.isEmpty()) {
                // No? No worries, let's just click on the label instead
                return WebElementFacadeImpl.fromWebElements(matchingLabelsWithForAttribute);
            } else {
                // If there is a for attribute, Find the field with that ID
                return WebElementFacadeImpl.fromWebElements(searchContext.findElements(By.id(fieldId)));
            }
        };
    }

    public static Function> findNestedElements(Target container, Target nestedElement) {
        return searchContext -> {
            // Find the first matching container
            return container.resolveAllFor(searchContext)
                    .stream()
                    .flatMap(
                            webElementFacade -> webElementFacade.withTimeoutOf(Duration.ZERO).findNestedElementsMatching(nestedElement).stream()
                    ).collect(Collectors.toList());
        };
    }

    public static Function> containingTextAndMatchingCSS(String cssOrXPathLocator, String expectedText) {
        return searchContext ->
                WebElementFacadeImpl.fromWebElements(
                        searchContext.findElements(Selectors.xpathOrCssSelector(cssOrXPathLocator))
                                .stream()
                                .filter(WebElement::isDisplayed)
                                .filter(element -> element.getAttribute("textContent").contains(expectedText))
                                .collect(Collectors.toList()));
    }


    public static Function> containingTextAndMatchingCSS(List cssOrXPathLocators, String expectedText) {
        return searchContext -> {
            List matchingElements = new ArrayList<>();
            for (String cssOrXPathLocator : cssOrXPathLocators) {
                matchingElements.addAll(
                        WebElementFacadeImpl.fromWebElements(
                                searchContext.findElements(Selectors.xpathOrCssSelector(cssOrXPathLocator))
                                        .stream()
                                        .filter(WebElement::isDisplayed)
                                        .filter(element -> element.getAttribute("textContent").contains(expectedText))
                                        .collect(Collectors.toList()))
                );
            }
            return WebElementFacadeImpl.fromWebElements(matchingElements);
        };
    }

    public static Function> containingTextAndMatchingCSSIgnoringCase(String cssOrXPathLocator, String expectedText) {
        return searchContext ->
                WebElementFacadeImpl.fromWebElements(
                        searchContext.findElements(Selectors.xpathOrCssSelector(cssOrXPathLocator))
                                .stream()
                                .filter(WebElement::isDisplayed)
                                .filter(element -> element.getAttribute("textContent").toLowerCase().contains(expectedText.toLowerCase()))
                                .collect(Collectors.toList()));
    }


    public static Function> containingTextAndMatchingCSSIgnoringCase(List cssOrXPathLocators, String expectedText) {
        return searchContext -> {
            List matchingElements = new ArrayList<>();
            for (String cssOrXPathLocator : cssOrXPathLocators) {
                matchingElements.addAll(
                        WebElementFacadeImpl.fromWebElements(
                                searchContext.findElements(Selectors.xpathOrCssSelector(cssOrXPathLocator))
                                        .stream()
                                        .filter(WebElement::isDisplayed)
                                        .filter(element -> element.getAttribute("textContent").toLowerCase().contains(expectedText.toLowerCase()))
                                        .collect(Collectors.toList()))
                );
            }
            return WebElementFacadeImpl.fromWebElements(matchingElements);
        };
    }

    public static Function> containingTextAndBy(By byLocator, String expectedText) {
        return searchContext ->
                WebElementFacadeImpl.fromWebElements(
                        searchContext.findElements(byLocator)
                                .stream()
                                .filter(WebElement::isDisplayed)
                                .filter(element -> containsText(element,expectedText))
                                .collect(Collectors.toList())
                );
    }

    public static Function> containingTextAndByIgnoringCase(By byLocator, String expectedText) {
        return searchContext ->
                WebElementFacadeImpl.fromWebElements(
                        searchContext.findElements(byLocator)
                                .stream()
                                .filter(WebElement::isDisplayed)
                                .filter(element -> containsTextIgnoringCase(element,expectedText))
                                .collect(Collectors.toList())
                );
    }

    private static boolean containsText(WebElement element, String expectedText) {
        return element.getText().contains(expectedText);
    }

    private static boolean containsTextIgnoringCase(WebElement element, String expectedText) {
        return element.getText().toLowerCase().contains(expectedText.toLowerCase());
    }

    private static String labelsWithText(String labelText) {
        return ".//label[normalize-space(.)='" + CSSAttributeValue.withEscapedQuotes(labelText) + "']";
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy