org.apache.falcon.regression.ui.search.SearchPage.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.falcon.regression.ui.search.SearchPage.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.falcon.regression.ui.search;

import org.apache.commons.lang.StringUtils;
import org.apache.falcon.entity.v0.Entity;
import org.apache.falcon.regression.Entities.FeedMerlin;
import org.apache.falcon.regression.Entities.ProcessMerlin;
import org.apache.falcon.regression.core.util.UIAssert;
import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

/** Page object for the Search Page. */
public class SearchPage extends AbstractSearchPage {

    private static final String CLASS_OF_SELECTED_ROW = "rowSelected";

    private static final Logger LOGGER = Logger.getLogger(SearchPage.class);

    public SearchPage(WebDriver driver) {
        super(driver);
    }

    @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "searchBoxContainer") })
    private WebElement searchBlock;

    @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "dashboardBox") })
    private WebElement resultBlock;

    @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "dashboardBox"), @FindBy(tagName = "thead") })
    private WebElement resultHeader;

    @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "dashboardBox"),
            @FindBy(className = "buttonRow") })
    private WebElement resultButtons;

    private List<WebElement> getSearchResultElements() {
        return resultBlock.findElements(By.className("entityRow"));
    }

    public List<SearchResult> getSearchResults() {
        List<SearchResult> searchResults = new ArrayList<>();
        for (WebElement oneResultElement : getSearchResultElements()) {
            final List<WebElement> resultParts = oneResultElement.findElements(By.tagName("td"));
            final String entityName = resultParts.get(1).getText();
            final SearchResult searchResult = SearchResult.create(entityName);

            final String[] allClasses = oneResultElement.getAttribute("class").split(" ");
            if (Arrays.asList(allClasses).contains(CLASS_OF_SELECTED_ROW)) {
                searchResult.withChecked(true);
            }

            final String tags = resultParts.get(2).getText();
            searchResult.withTags(tags);

            final String clusterName = resultParts.get(3).getText();
            searchResult.withClusterName(clusterName);

            final String type = resultParts.get(4).getText();
            searchResult.withType(type);

            final String status = resultParts.get(5).getText();
            searchResult.withStatus(status);
            searchResults.add(searchResult);
        }
        return searchResults;
    }

    public EntityPage openEntityPage(String entityName) {
        return click(doSearch(entityName).get(0));
    }

    public EntityPage click(SearchResult result) {
        LOGGER.info("attempting to click: " + result + " on search page.");
        for (WebElement oneResultElement : getSearchResultElements()) {
            final List<WebElement> resultParts = oneResultElement.findElements(By.tagName("td"));
            final WebElement entityNameElement = resultParts.get(1);
            final String entityName = entityNameElement.getText();
            if (entityName.equals(result.getEntityName())) {
                entityNameElement.findElement(By.tagName("button")).click();
                return PageFactory.initElements(driver, EntityPage.class);
            }
        }
        return null;
    }

    @Override
    public void checkPage() {
        UIAssert.assertDisplayed(searchBlock, "Cluster box");
    }

    private WebElement getSearchBox() {
        return searchBlock.findElement(By.className("input"));
    }

    public List<SearchResult> doSearch(String searchString) {
        clearSearch();
        return appendAndSearch(searchString);
    }

    public List<SearchResult> appendAndSearch(String appendedPart) {
        for (String queryParam : appendedPart.split("\\s+")) {
            focusOnSearchBox();
            getSearchBox().sendKeys(queryParam);
            getSearchBox().sendKeys(Keys.ENTER);
        }
        waitForAngularToFinish();
        if (resultBlock.isDisplayed()) {
            return getSearchResults();
        } else {
            return Collections.emptyList();
        }

    }

    public SearchQuery getSearchQuery() {
        return new SearchQuery(searchBlock);
    }

    public void clearSearch() {
        focusOnSearchBox();
        getSearchBox().clear();
        SearchQuery query = getSearchQuery();
        for (int i = 0; i < query.getElementsNumber(); i++) {
            removeLastParam();
        }
    }

    public void removeLastParam() {
        focusOnSearchBox();
        getSearchBox().sendKeys(Keys.BACK_SPACE);
        getSearchBox().sendKeys(Keys.BACK_SPACE);
    }

    private void focusOnSearchBox() {
        driver.findElement(By.className("tags")).click();
    }

    public void checkNoResult() {
        UIAssert.assertNotDisplayed(resultBlock, "Search result block");
    }

    public void selectRow(int row) {
        changeRowClickedStatus(row, true);
    }

    public void deselectRow(int row) {
        changeRowClickedStatus(row, false);
    }

    private void changeRowClickedStatus(int row, boolean checked) {
        WebElement checkboxBlock = resultBlock.findElements(By.className("entityRow")).get(row - 1);
        if (checked != checkboxBlock.getAttribute("class").contains(CLASS_OF_SELECTED_ROW)) {
            checkboxBlock.findElement(By.xpath("./td/input")).click();
        }
    }

    public void clickSelectAll() {
        resultBlock.findElement(By.xpath(".//input[@ng-model='selectedAll']")).click();
    }

    /** Class representing search query displayed in the search box. */
    public static final class SearchQuery {
        private WebElement searchBlock;
        private String name;
        private String type;
        private int elementsNumber;
        private final List<String> tags = new ArrayList<>();
        private static final Logger LOGGER = Logger.getLogger(SearchQuery.class);

        public SearchQuery(WebElement searchBlock) {
            this.searchBlock = searchBlock;
            updateElements();
        }

        private SearchQuery updateElements() {
            name = null;
            tags.clear();
            final WebElement queryGroup = searchBlock.findElement(By.className("tag-list"));
            final List<WebElement> queryParts = queryGroup.findElements(By.tagName("li"));
            elementsNumber = queryParts.size();
            for (WebElement queryPart : queryParts) {
                final WebElement queryLabel = queryPart.findElement(By.tagName("strong"));
                final String queryText = queryPart.findElement(By.tagName("span")).getText();
                switch (queryLabel.getText().trim()) {
                case "Name:":
                    if (name != null) {
                        LOGGER.warn(String.format("NAME block is already added: '%s' => '%s'", name, queryText));
                    }
                    name = queryText;
                    break;
                case "Tag:":
                    tags.add(queryText);
                    break;
                default:
                }
            }
            return this;
        }

        public String getName() {
            return name;
        }

        public List<String> getTags() {
            return tags;
        }

        public int getElementsNumber() {
            return elementsNumber;
        }

        /**
         * Delete element by index (1, 2, 3,..).
         * @param index of element in search query.
         * @return true if deletion was successful
         */
        public boolean deleteByIndex(int index) {
            if (index > elementsNumber || index < 1) {
                LOGGER.warn("There is no element with index=" + index);
                return false;
            }
            int oldElementsNumber = elementsNumber;
            final WebElement queryGroup = searchBlock.findElement(By.className("tag-list"));
            final List<WebElement> queryParts = queryGroup.findElements(By.tagName("li"));
            queryParts.get(index - 1).findElement(By.className("remove-button")).click();
            this.updateElements();
            boolean result = oldElementsNumber == elementsNumber + 1;
            LOGGER.info(String.format("Element with index=%d was%s deleted", index, result ? "" : "n't"));
            return result;
        }

        public boolean deleteLast() {
            return deleteByIndex(elementsNumber);
        }
    }

    public Set<Button> getButtons(boolean active) {
        List<WebElement> buttons = resultBlock.findElement(By.className("buttonsRow"))
                .findElements(By.className("btn"));
        Set<Button> result = EnumSet.noneOf(Button.class);
        for (WebElement button : buttons) {
            if ((button.getAttribute("disabled") == null) == active) {
                result.add(Button.valueOf(button.getText()));
            }
        }
        return result;
    }

    public void clickButton(Button button) {
        resultBlock.findElement(By.className("buttonsRow")).findElements(By.className("btn")).get(button.ordinal())
                .click();
        waitForAngularToFinish();
    }

    /**
     * Buttons available for entities in result box.
     */
    public enum Button {
        Schedule, Resume, Suspend, Edit, Copy, Delete, XML
    }

    /** Class representing search result displayed on the entity table page. */
    public static final class SearchResult {
        private boolean isChecked = false;
        private String entityName;
        private String tags = "";
        private String clusterName;
        private String type;
        private EntityStatus status;

        public static SearchResult create(String entityName) {
            return new SearchResult(entityName);
        }

        public SearchResult withChecked(boolean pIsChecked) {
            this.isChecked = pIsChecked;
            return this;
        }

        private SearchResult(String entityName) {
            this.entityName = entityName;
        }

        public SearchResult withTags(String pTags) {
            this.tags = pTags;
            return this;
        }

        public SearchResult withClusterName(String pClusterName) {
            this.clusterName = pClusterName;
            return this;
        }

        public SearchResult withType(String pType) {
            this.type = pType;
            return this;
        }

        public SearchResult withStatus(String pStatus) {
            this.status = EntityStatus.valueOf(pStatus);
            return this;
        }

        public boolean isChecked() {
            return isChecked;
        }

        public String getEntityName() {
            return entityName;
        }

        public String getTags() {
            return tags;
        }

        public String getClusterName() {
            Assert.assertFalse(clusterName.contains(","), "getClusterName() called" + " in multi-cluster setup: "
                    + clusterName + ", maybe use getClusterNames()");
            return clusterName;
        }

        public List<String> getClusterNames() {
            return Arrays.asList(clusterName.split(","));
        }

        public String getType() {
            return type;
        }

        public EntityStatus getStatus() {
            return status;
        }

        @Override
        public String toString() {
            return "SearchResult{" + "isChecked=" + isChecked + ", entityName='" + entityName + '\'' + ", tags='"
                    + tags + '\'' + ", clusterName='" + clusterName + '\'' + ", type='" + type + '\'' + ", status='"
                    + status + '\'' + '}';
        }

        public static void assertEqual(List<SearchResult> searchResults, List<Entity> expectedEntities,
                String errorMessage) {
            Assert.assertEquals(searchResults.size(), expectedEntities.size(),
                    errorMessage + "(Length of lists don't match, searchResults: " + searchResults
                            + " expectedEntities: " + expectedEntities + ")");
            for (Entity entity : expectedEntities) {
                boolean found = false;
                for (SearchResult result : searchResults) {
                    //entities are same if they have same name & type
                    if (entity.getName().equals(result.entityName)) {
                        //entity type in SearchResults has a different meaning
                        //so, not comparing entity types

                        //equality of cluster names
                        List<String> entityClusters = null;
                        switch (entity.getEntityType()) {
                        case FEED:
                            final FeedMerlin feed = (FeedMerlin) entity;
                            entityClusters = feed.getClusterNames();
                            // tags equality check
                            Assert.assertEquals(result.getTags(), StringUtils.trimToEmpty(feed.getTags()),
                                    errorMessage + "(tags mismatch: " + result.entityName + " & "
                                            + entity.toShortString() + ")");
                            break;
                        case PROCESS:
                            final ProcessMerlin process = (ProcessMerlin) entity;
                            entityClusters = process.getClusterNames();
                            // tags equality check
                            Assert.assertEquals(result.getTags(), StringUtils.trimToEmpty(process.getTags()),
                                    errorMessage + "(tags mismatch: " + result.entityName + " & "
                                            + entity.toShortString() + ")");
                            break;
                        default:
                            Assert.fail("Cluster entity is unexpected: " + entity);
                            break;
                        }
                        Collections.sort(entityClusters);
                        final List<String> actualClusters = result.getClusterNames();
                        Collections.sort(actualClusters);
                        Assert.assertEquals(actualClusters, entityClusters,
                                errorMessage + "(cluster names mismatch: " + result + " " + entity + ")");
                        found = true;
                    }
                }
                Assert.assertTrue(found, "Entity: " + entity.toShortString() + " not found in: " + searchResults);
            }
        }

    }

}