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

Java tutorial

Introduction

Here is the source code for org.apache.falcon.regression.ui.search.ClusterWizardPage.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.cluster.ACL;
import org.apache.falcon.entity.v0.cluster.ClusterLocationType;
import org.apache.falcon.entity.v0.cluster.Interface;
import org.apache.falcon.entity.v0.cluster.Interfacetype;
import org.apache.falcon.entity.v0.cluster.Location;
import org.apache.falcon.entity.v0.cluster.Property;
import org.apache.falcon.regression.Entities.ClusterMerlin;
import org.apache.falcon.regression.core.util.UIAssert;
import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.testng.Assert;

import java.util.List;

/** Page object of the Cluster creation page. */
public class ClusterWizardPage extends EntityWizardPage {
    private static final Logger LOGGER = Logger.getLogger(ClusterWizardPage.class);
    @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "clusterForm") })
    private WebElement clusterBox;
    @FindBy(id = "cluster.step1")
    private WebElement next;
    @FindBy(id = "cluster.step2")
    private WebElement save;
    @FindBy(id = "cluster.backToStep1")
    private WebElement previous;
    @FindBy(xpath = "//a[contains(text(), 'Cancel')]")
    private WebElement cancel;
    @FindBy(xpath = "//div[contains(@class, 'clusterSummaryRow')][h4]")
    private WebElement summaryBox;

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

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

    /**
     * Fills cluster setup forms with values retrieved from Filling object.
     */
    public void fillForm(ClusterMerlin cluster) {
        setName(cluster.getName());
        setColo(cluster.getColo());
        setDescription(cluster.getDescription());
        setTags(cluster.getTags());
        ACL acl = cluster.getACL();
        setOwner(acl.getOwner());
        setGroup(acl.getGroup());
        setPermissions(acl.getPermission());
        for (Interface iface : cluster.getInterfaces().getInterfaces()) {
            setInterface(iface);
        }
        for (Property property : cluster.getProperties().getProperties()) {
            addProperty(property.getName(), property.getValue());
        }
        setLocations(cluster.getLocations().getLocations());
        waitForAngularToFinish();
    }

    /**
     * Methods to fill specific wizard fields.
     */
    public void setName(String name) {
        WebElement nameInput = getNameInput();
        nameInput.clear();
        sendKeysSlowly(nameInput, name);
    }

    public String getName() {
        return getNameInput().getAttribute("value");
    }

    private WebElement getNameInput() {
        return driver.findElement(By.xpath("//div[label[text()='Name']]/input"));
    }

    public void setColo(String colo) {
        WebElement coloInput = clusterBox.findElement(By.xpath("//div[label[text()='Colo']]/input"));
        coloInput.clear();
        sendKeysSlowly(coloInput, colo);
    }

    public void setDescription(String description) {
        WebElement descriptionInput = clusterBox.findElement(By.xpath("//div[label[text()='Description']]/input"));
        descriptionInput.clear();
        sendKeysSlowly(descriptionInput, description);
    }

    public void setOwner(String owner) {
        WebElement ownerInput = clusterBox.findElement(By.xpath("//div[label[text()='Owner']]/input"));
        ownerInput.clear();
        sendKeysSlowly(ownerInput, owner);
    }

    public void setGroup(String group) {
        WebElement groupInput = clusterBox.findElement(By.xpath("//div[label[text()='Group']]/input"));
        groupInput.clear();
        sendKeysSlowly(groupInput, group);
    }

    public void setPermissions(String permissions) {
        WebElement permissionsInput = clusterBox.findElement(By.xpath("//div[label[text()='Permissions']]/input"));
        permissionsInput.clear();
        sendKeysSlowly(permissionsInput, permissions);
    }

    /**
     * Common method to fill interfaces.
     */
    public void setInterface(Interface iface) {
        String xpath = "//input[contains(@ng-model,"
                + " 'clusterEntity.clusterModel.cluster.interfaces.interface[%sPos]._endpoint')]";
        WebElement ifaceEndpoint = clusterBox.findElement(By.xpath(String.format(xpath, iface.getType().value())));
        ifaceEndpoint.clear();
        sendKeysSlowly(ifaceEndpoint, iface.getEndpoint());
        setInterfaceVersion(iface);
    }

    /**
     * Set interface version by interface type.
     */
    public void setInterfaceVersion(Interface iface) {
        WebElement ifaceVersion = getInterfaceVersionInput(iface.getType());
        if (iface.getVersion() != null) {
            ifaceVersion.clear();
            sendKeysSlowly(ifaceVersion, iface.getVersion());
        }
    }

    /**
     * Get input for interface version by interface type.
     */
    private WebElement getInterfaceVersionInput(Interfacetype interfacetype) {
        return clusterBox.findElement(By.xpath(String.format(
                "//input[@ng-model='clusterEntity.clusterModel.cluster.interfaces.interface[%sPos]._version']",
                interfacetype.value())));
    }

    /**
     * Populates form with tags.
     */
    public void setTags(String tagsStr) {
        if (!StringUtils.isEmpty(tagsStr)) {
            String[] tags = tagsStr.split(",");
            for (int i = 0; i < tags.length; i++) {
                if (i > 0) {
                    clickAddTag();
                }
                String key = tags[i].trim().split("=")[0];
                String value = tags[i].trim().split("=")[1];
                addTag(key, value);
            }
        }
    }

    /**
     * Populates last (empty) tag and value fields and creates new fields.
     * @param key tag key
     * @param value tag value
     */
    public void addTag(String key, String value) {
        List<WebElement> tagInputs = clusterBox.findElements(By.xpath("//input[@ng-model='tag.key']"));
        List<WebElement> valueInputs = clusterBox.findElements(By.xpath("//input[@ng-model='tag.value']"));
        WebElement tagInput = tagInputs.get(tagInputs.size() - 1);
        sendKeysSlowly(tagInput, key);
        WebElement valueInput = valueInputs.get(valueInputs.size() - 1);
        sendKeysSlowly(valueInput, value);
    }

    public void clickAddTag() {
        clusterBox.findElement(By.xpath("//button[contains(., 'add tag')]")).click();
    }

    public void clickDeleteTag() {
        List<WebElement> buttons = clusterBox.findElements(
                By.xpath("//div[@class='row dynamic-table-spacer ng-scope']//button[contains(.,'delete')]"));
        buttons.get(buttons.size() - 1).click();
    }

    /**
     * Fills property fields and creates new empty property fields.
     */
    public void addProperty(String name, String value) {
        List<WebElement> propInputs = clusterBox.findElements(By.xpath("//input[@ng-model='property._name']"));
        List<WebElement> valueInputs = clusterBox.findElements(By.xpath("//input[@ng-model='property._value']"));
        WebElement propInput = propInputs.get(propInputs.size() - 1);
        sendKeysSlowly(propInput, name);
        WebElement valueInput = valueInputs.get(valueInputs.size() - 1);
        sendKeysSlowly(valueInput, value);
        clickAddProperty();
    }

    public void clickAddProperty() {
        clusterBox.findElement(By.xpath("//button[contains(., 'add property')]")).click();
    }

    /**
     * Method to set locations. Location can be only one of ClusterLocationType. So adding new location only after
     * respective compulsory location was filled.
     * @param locations locations
     */
    public void setLocations(List<Location> locations) {
        boolean staging = false, temp = false, working = false;
        for (Location location : locations) {
            WebElement pathInput = null;
            if (location.getName() == ClusterLocationType.STAGING && !staging) {
                pathInput = clusterBox.findElement(By.id("location.staging"));
                staging = true;
            } else if (location.getName() == ClusterLocationType.TEMP && !temp) {
                pathInput = clusterBox.findElement(By.id("location.temp"));
                temp = true;
            } else if (location.getName() == ClusterLocationType.WORKING && !working) {
                pathInput = clusterBox.findElement(By.id("location.working"));
                working = true;
            } else {
                fillAdditionalLocation(location);
            }
            if (pathInput != null) {
                pathInput.clear();
                sendKeysSlowly(pathInput, location.getPath());
            }
        }
    }

    /**
     * Method populates last location fields with values and creates new fields.
     */
    public void fillAdditionalLocation(Location location) {
        List<WebElement> allNameInputs = clusterBox
                .findElements(By.xpath("//input[contains(@ng-model, 'location._name')]"));
        sendKeysSlowly(allNameInputs.get(allNameInputs.size() - 1), location.getName().value());
        List<WebElement> allPathInputs = clusterBox
                .findElements(By.xpath("//input[contains(@ng-model, 'location._path')]"));
        sendKeysSlowly(allPathInputs.get(allPathInputs.size() - 1), location.getPath());
    }

    public void clickAddLocation() {
        clusterBox.findElement(By.xpath("//button[contains(., 'add location')]")).click();
    }

    public void clickDeleteLocation() {
        List<WebElement> buttons = clusterBox
                .findElements(By.xpath("//div[@class='row ng-scope']//button[contains(.,'delete')]"));
        Assert.assertFalse(buttons.isEmpty(), "Delete button should be present.");
        buttons.get(buttons.size() - 1).click();
    }

    public boolean checkElementByContent(String elementTag, String content) {
        List<WebElement> elements = clusterBox.findElements(By.xpath("//" + elementTag));
        for (WebElement element : elements) {
            if (element.getAttribute("value").equals(content)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Method to assert the staging and Working location are same.
     */
    public void assertLocationsEqualError() {

        // Assertion for Staging Location.
        LOGGER.info(" Assertion for Staging Directory ");
        Assert.assertTrue(checkErrorMessageByElement(
                "input[contains(@id,'location.staging')]//following-sibling::"
                        + "span[contains(@ng-show, 'locationsEqualError')]",
                "Staging and Working location should be different"));

        // Assertion for Working Location.
        LOGGER.info("Assertion for Working Directory");
        Assert.assertTrue(checkErrorMessageByElement(
                "input[contains(@id,'location.working')]//following-sibling::"
                        + "span[contains(@ng-show, 'locationsEqualError')]",
                "Staging and Working location should be different"));
    }

    /**
     * Method to get the Error text message displayed based on Xpath and compares.
     * with the input string paramater : errMessage
     * @param elementTag elementTag
     * @param errMessage errMessage
     */
    public boolean checkErrorMessageByElement(String elementTag, String errMessage) {

        List<WebElement> elements = clusterBox.findElements(By.xpath("//" + elementTag));
        if (!elements.isEmpty()) {
            for (WebElement element : elements) {
                Assert.assertEquals(element.getText(), errMessage);
                LOGGER.info("Error Message Displayed : " + element.getText());
            }
            return true;
        } else {
            LOGGER.info(" No Elements found with the xpath " + elementTag);
            return false;
        }
    }

    /**
     * Retrieves the value of the summary box and parses it to cluster properties.
     * @param draft empty cluster to contain all properties.
     * @return cluster filled with properties from the summary.
     */
    public ClusterMerlin getSummary(ClusterMerlin draft) {
        ClusterMerlin cluster = new ClusterMerlin(draft.toString());
        String summaryBoxText = summaryBox.getText();
        LOGGER.info("Summary block text : " + summaryBoxText);

        String[] slices;
        String value;
        String path;
        String label;

        //retrieve basic properties
        String basicProps = summaryBoxText.split("ACL")[0];
        for (String line : basicProps.split("\\n")) {
            slices = line.split(" ");
            label = slices[0].replace(":", "").trim();
            value = getValueFromSlices(slices, line);
            switch (label) {
            case "Name":
                cluster.setName(value);
                break;
            case "Colo":
                cluster.setColo(value);
                break;
            case "Description":
                cluster.setDescription(value);
                break;
            case "Tags":
                cluster.setTags(value);
                break;
            default:
                break;
            }
        }
        //retrieve ALC
        String propsLeft = summaryBoxText.split("ACL")[1];
        String[] acl = propsLeft.split("Interfaces")[0].split(" ");
        cluster.getACL().setOwner(acl[1]);
        cluster.getACL().setGroup(acl[3]);
        cluster.getACL().setPermission(acl[5].trim());

        //retrieve interfaces
        propsLeft = propsLeft.split("Interfaces")[1];
        boolean propertiesPresent = propsLeft.contains("Properties");
        String nextLabel = propertiesPresent ? "Properties" : "Locations";
        String interfaces = propsLeft.split(nextLabel)[0].trim();
        for (String line : interfaces.split("\\n")) {
            slices = line.split(" ");
            label = slices[0].replace(":", "").trim();
            String endpoint = slices[1].trim();
            String version = slices[3].trim();
            switch (label) {
            case "readonly":
                cluster.addInterface(Interfacetype.READONLY, endpoint, version);
                break;
            case "write":
                cluster.addInterface(Interfacetype.WRITE, endpoint, version);
                break;
            case "execute":
                cluster.addInterface(Interfacetype.EXECUTE, endpoint, version);
                break;
            case "workflow":
                cluster.addInterface(Interfacetype.WORKFLOW, endpoint, version);
                break;
            case "messaging":
                cluster.addInterface(Interfacetype.MESSAGING, endpoint, version);
                break;
            case "registry":
                cluster.addInterface(Interfacetype.REGISTRY, endpoint, version);
                break;
            default:
                break;
            }
        }
        //retrieve properties
        if (propertiesPresent) {
            propsLeft = propsLeft.split("Properties")[1];
            String properties = propsLeft.split("Locations")[0].trim();
            for (String line : properties.split("\\n")) {
                int indx = line.indexOf(":");
                String name = line.substring(0, indx).trim();
                value = line.substring(indx + 1, line.length()).trim();
                cluster.withProperty(name, value);
            }
        }
        //retrieve locations
        propsLeft = propsLeft.split("Locations")[1].trim();
        for (String line : propsLeft.split("\\n")) {
            slices = line.split(" ");
            label = slices[0].replace(":", "").trim();
            path = getValueFromSlices(slices, line);
            switch (label) {
            case "staging":
                cluster.addLocation(ClusterLocationType.STAGING, path);
                break;
            case "temp":
                cluster.addLocation(ClusterLocationType.TEMP, path);
                break;
            default:
                cluster.addLocation(ClusterLocationType.WORKING, path);
                break;
            }
        }
        return cluster;
    }

    /**
     * Clicks on cancel button.
     */
    public void cancel() {
        cancel.click();
    }

    /**
     *  Click on next button which is the same as finish step 1.
     */
    public void clickNext() {
        next.click();
        waitForAngularToFinish();
        Assert.assertTrue(summaryBox.isDisplayed(), "Summary box should be displayed.");
    }

    /**
     *  Click on next button in the cluster creation page.
     */
    public void clickJustNext() {
        next.click();
        waitForAngularToFinish();
    }

    /**
     * Click on save button.
     */
    public void clickSave() {
        save.click();
        waitForAlert();
    }

    /**
     * Clicks on previous button.
     */
    public void clickPrevious() {
        previous.click();
        waitForAngularToFinish();
        UIAssert.assertDisplayed(clusterBox, "Cluster box");
    }

    /**
     * Method imitates click on check box.
     * @param expectedState whether check box is expected to be enabled or not after click.
     */
    public void checkRegistry(boolean expectedState) {
        WebElement checkbox = clusterBox.findElement(By.xpath("//input[@type='checkbox']"));
        clickCheckBoxSecurely(checkbox, expectedState);
        waitForAngularToFinish();
    }

    public WebElement getInterfaceEndpoint(Interfacetype interfacetype) {
        String xpath = String.format("//input[@ng-model='clusterEntity.clusterModel.cluster.interfaces"
                + ".interface[%sPos]._endpoint']", interfacetype.value());
        return clusterBox.findElement(By.xpath(xpath));
    }

    public String getInterfaceEndpointValue(Interfacetype interfacetype) {
        return getInterfaceEndpoint(interfacetype).getAttribute("value");
    }

    public WebElement getInterfaceVersion(Interfacetype interfacetype) {
        String xpath = String.format(
                "//input[@ng-model='clusterEntity.clusterModel.cluster.interfaces" + ".interface[%sPos]._version']",
                interfacetype.value());
        return clusterBox.findElement(By.xpath(xpath));
    }

    public String getInterfaceVersionValue(Interfacetype interfacetype) {
        return getInterfaceVersion(interfacetype).getAttribute("value");
    }

    /**
     * Method preventing the NullPointerException.
     */
    public String getValueFromSlices(String[] slices, String line) {
        String trimValue;
        if (slices[0].length() == (line.length())) {
            trimValue = "";
        } else {
            trimValue = slices[1].trim();
        }
        return trimValue;
    }

    /**
     * Checks whether registry interface is enabled for input or not.
     */
    public boolean isRegistryEnabled() {
        return getInterfaceEndpoint(Interfacetype.REGISTRY).isEnabled()
                && getInterfaceVersion(Interfacetype.REGISTRY).isEnabled();
    }

    private WebElement getNameUnavailable() {
        return clusterBox.findElement(
                By.xpath("//div[contains(@class, 'nameInputDisplay') and contains(@class, 'custom-danger')]"));
    }

    public void checkNameUnavailableDisplayed(boolean isDisplayed) {
        if (isDisplayed) {
            UIAssert.assertDisplayed(getNameUnavailable(), "Name Unavailable not displayed");
        } else {
            try {
                getNameUnavailable();
                Assert.fail("Name Unavailable found");
            } catch (Exception ex) {
                LOGGER.info("Name Unavailable not found");
            }
        }
    }

    @Override
    public WebElement getEditXMLButton() {
        return driver.findElement(By.id("cluster.editXML"));
    }

    @Override
    public ClusterMerlin getEntityFromXMLPreview() {
        return new ClusterMerlin(getXMLPreview());
    }
}