falcon-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rag...@apache.org
Subject [2/2] falcon git commit: FALCON-1249 Tests for process setup wizard conributed by Namit Maheshwari and Paul Isaychuk
Date Thu, 04 Jun 2015 18:53:01 GMT
FALCON-1249 Tests for process setup wizard conributed by Namit Maheshwari and Paul Isaychuk


Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/ff9c78e3
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/ff9c78e3
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/ff9c78e3

Branch: refs/heads/master
Commit: ff9c78e3c82e45a4e3543924fffe834773dc3880
Parents: 8ee6d45
Author: Raghav Kumar Gautam <raghav@apache.org>
Authored: Thu Jun 4 11:51:00 2015 -0700
Committer: Raghav Kumar Gautam <raghav@apache.org>
Committed: Thu Jun 4 11:52:46 2015 -0700

----------------------------------------------------------------------
 falcon-regression/CHANGES.txt                   |   2 +
 .../regression/Entities/ProcessMerlin.java      | 178 +++-
 .../ui/search/AbstractSearchPage.java           |   1 +
 .../regression/ui/search/ProcessWizardPage.java | 806 ++++++++++++++-
 .../regression/searchUI/ProcessSetupTest.java   | 982 ++++++++++++++++++-
 5 files changed, 1919 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/falcon/blob/ff9c78e3/falcon-regression/CHANGES.txt
----------------------------------------------------------------------
diff --git a/falcon-regression/CHANGES.txt b/falcon-regression/CHANGES.txt
index d9af012..46799e8 100644
--- a/falcon-regression/CHANGES.txt
+++ b/falcon-regression/CHANGES.txt
@@ -5,6 +5,8 @@ Trunk (Unreleased)
   INCOMPATIBLE CHANGES
 
   NEW FEATURES
+   FALCON-1249 Tests for process setup wizard (Namit Maheshwari and Paul Isaychuk)
+
    FALCON-1242 Search UI test for entity upload button (Namit Maheshwari)
 
    FALCON-1222 Feed Wizard multiple tests (Namit Maheshwari)

http://git-wip-us.apache.org/repos/asf/falcon/blob/ff9c78e3/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
index 9e3d2d7..615587d 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/Entities/ProcessMerlin.java
@@ -38,16 +38,22 @@ import org.apache.falcon.entity.v0.process.Property;
 import org.apache.falcon.entity.v0.process.Validity;
 import org.apache.falcon.entity.v0.process.Workflow;
 import org.apache.falcon.regression.core.util.TimeUtil;
+import org.apache.falcon.regression.core.util.Util;
+import org.apache.log4j.Logger;
 import org.testng.Assert;
+import org.testng.asserts.SoftAssert;
 
 import javax.xml.bind.JAXBException;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 /** Class for representing a process xml. */
 public class ProcessMerlin extends Process {
+    private static final Logger LOGGER = Logger.getLogger(ProcessMerlin.class);
     public ProcessMerlin(String processData) {
         this((Process) TestEntityUtil.fromString(EntityType.PROCESS, processData));
     }
@@ -87,6 +93,34 @@ public class ProcessMerlin extends Process {
         return null;
     }
 
+    /**
+     * Compares two process cluster lists, if they are equal or not.
+     */
+    public static void assertClustersEqual(List<Cluster> clusters1, List<Cluster>
clusters2) {
+        if (clusters1.size() != clusters2.size()) {
+            Assert.fail("Cluster sizes are different.");
+        }
+        Comparator<Cluster> clusterComparator = new Comparator<Cluster>() {
+            @Override
+            public int compare(Cluster cluster1, Cluster cluster2) {
+                return cluster1.getName().compareTo(cluster2.getName());
+            }
+        };
+        Collections.sort(clusters1, clusterComparator);
+        Collections.sort(clusters2, clusterComparator);
+        SoftAssert softAssert = new SoftAssert();
+        for(int i = 0; i < clusters1.size(); i++) {
+            Cluster cluster1 = clusters1.get(i);
+            Cluster cluster2 = clusters2.get(i);
+            softAssert.assertEquals(cluster1.getName(), cluster2.getName(), "Cluster names
are different.");
+            softAssert.assertEquals(cluster1.getValidity().getStart(), cluster2.getValidity().getStart(),
+                String.format("Validity start is not the same for cluster %s", cluster1.getName()));
+            softAssert.assertEquals(cluster1.getValidity().getEnd(), cluster2.getValidity().getEnd(),
+                String.format("Cluster validity end is not the same for cluster %s", cluster1.getName()));
+        }
+        softAssert.assertAll();
+    }
+
     public Input getInputByName(String name) {
         for (Input input : getInputs().getInputs()) {
             if (input.getName().equals(name)) {
@@ -332,8 +366,6 @@ public class ProcessMerlin extends Process {
         getOutputs().getOutputs().add(out2);
     }
 
-
-
     /**
      * Adds one input into process.
      */
@@ -349,7 +381,6 @@ public class ProcessMerlin extends Process {
         getInputs().getInputs().add(in2);
     }
 
-
     public void setInputFeedWithEl(String inputFeedName, String startEl, String endEl) {
         Inputs inputs = new Inputs();
         Input input = new Input();
@@ -388,7 +419,6 @@ public class ProcessMerlin extends Process {
         this.setOutputs(outputs);
     }
 
-
     /**
      * Sets partition for each input, according to number of supplied partitions.
      *
@@ -432,8 +462,6 @@ public class ProcessMerlin extends Process {
         this.setTimeout(frq);
     }
 
-
-
     public void setWorkflow(String wfPath, String libPath, EngineType engineType) {
         Workflow w = this.getWorkflow();
         if (engineType != null) {
@@ -455,6 +483,144 @@ public class ProcessMerlin extends Process {
         return EntityType.PROCESS;
     }
 
+    public void assertGeneralProperties(ProcessMerlin newProcess){
+        SoftAssert softAssert = new SoftAssert();
+        // Assert all the the General Properties
+        softAssert.assertEquals(newProcess.getName(), getName(),
+            "Process Name is different");
+        softAssert.assertEquals(newProcess.getTags(), getTags(),
+            "Process Tags Value is different");
+        softAssert.assertEquals(newProcess.getWorkflow().getName(), getWorkflow().getName(),
+            "Process Workflow Name is different");
+        if (getWorkflow().getEngine() == EngineType.OOZIE || getWorkflow().getEngine() ==
null) {
+            softAssert.assertTrue(newProcess.getWorkflow().getEngine() == EngineType.OOZIE
+                || newProcess.getWorkflow().getEngine() == null, "Process Workflow Engine
is different");
+        } else {
+            softAssert.assertEquals(newProcess.getWorkflow().getEngine().toString(),
+                getWorkflow().getEngine().toString(),
+                "Process Workflow Engine is different");
+        }
+        softAssert.assertEquals(newProcess.getWorkflow().getPath(), getWorkflow().getPath(),
+            "Process Workflow Path is different");
+        softAssert.assertEquals(newProcess.getACL().getOwner(), getACL().getOwner(),
+            "Process ACL Owner is different");
+        softAssert.assertEquals(newProcess.getACL().getGroup(), getACL().getGroup(),
+            "Process ACL Group is different");
+        softAssert.assertEquals(newProcess.getACL().getPermission(), getACL().getPermission(),
+            "Process ACL Permission is different");
+        softAssert.assertAll();
+    }
+
+    public void assertPropertiesInfo(ProcessMerlin newProcess){
+        SoftAssert softAssert = new SoftAssert();
+        // Assert all the Properties Info
+        softAssert.assertEquals(newProcess.getTimezone().getID(), getTimezone().getID(),
+            "Process TimeZone is different");
+        softAssert.assertEquals(newProcess.getFrequency().getFrequency(), getFrequency().getFrequency(),
+            "Process Frequency is different");
+        softAssert.assertEquals(newProcess.getFrequency().getTimeUnit().toString(),
+            getFrequency().getTimeUnit().toString(),
+            "Process Frequency Unit is different");
+        softAssert.assertEquals(newProcess.getParallel(), getParallel(),
+            "Process Parallel is different");
+        softAssert.assertEquals(newProcess.getOrder(), getOrder(),
+            "Process Order is different");
+        softAssert.assertEquals(newProcess.getRetry().getPolicy().value(),
+            getRetry().getPolicy().value(),
+            "Process Retry Policy is different");
+        softAssert.assertEquals(newProcess.getRetry().getAttempts(),
+            getRetry().getAttempts(),
+            "Process Retry Attempts is different");
+        softAssert.assertEquals(newProcess.getRetry().getDelay().getFrequency(),
+            getRetry().getDelay().getFrequency(),
+            "Process Delay Frequency is different");
+        softAssert.assertEquals(newProcess.getRetry().getDelay().getTimeUnit().name(),
+            getRetry().getDelay().getTimeUnit().name(),
+            "Process Delay Unit is different");
+        softAssert.assertAll();
+    }
+
+    /**
+     * Asserts equality of process inputs.
+     */
+    public void assertInputValues(ProcessMerlin newProcess){
+        Assert.assertEquals(newProcess.getInputs().getInputs().size(), getInputs().getInputs().size(),
+            "Processes have different number of inputs.");
+        SoftAssert softAssert = new SoftAssert();
+        // Assert all the Input values
+        for (int i = 0; i < newProcess.getInputs().getInputs().size(); i++) {
+            softAssert.assertEquals(newProcess.getInputs().getInputs().get(i).getName(),
+                getInputs().getInputs().get(i).getName(),
+                "Process Input Name is different");
+            softAssert.assertEquals(newProcess.getInputs().getInputs().get(i).getFeed(),
+                getInputs().getInputs().get(i).getFeed(),
+                "Process Input Feed is different");
+            softAssert.assertEquals(newProcess.getInputs().getInputs().get(i).getStart(),
+                getInputs().getInputs().get(i).getStart(),
+                "Process Input Start is different");
+            softAssert.assertEquals(newProcess.getInputs().getInputs().get(i).getEnd(),
+                getInputs().getInputs().get(i).getEnd(),
+                "Process Input End is different");
+        }
+        softAssert.assertAll();
+    }
+
+    /**
+     * Asserts equality of process outputs.
+     */
+    public void assertOutputValues(ProcessMerlin newProcess){
+        SoftAssert softAssert = new SoftAssert();
+        // Assert all the Output values
+        softAssert.assertEquals(newProcess.getOutputs().getOutputs().get(0).getName(),
+            getOutputs().getOutputs().get(0).getName(),
+            "Process Output Name is different");
+        softAssert.assertEquals(newProcess.getOutputs().getOutputs().get(0).getFeed(),
+            getOutputs().getOutputs().get(0).getFeed(),
+            "Process Output Feed is different");
+        softAssert.assertEquals(newProcess.getOutputs().getOutputs().get(0).getInstance(),
+            getOutputs().getOutputs().get(0).getInstance(),
+            "Process Output Instance is different");
+        softAssert.assertAll();
+    }
+
+    /**
+     * Asserts equality of two processes.
+     */
+    public void assertEquals(ProcessMerlin process) {
+        LOGGER.info(String.format("Comparing General Properties: source: %n%s%n and process:
%n%n%s",
+            Util.prettyPrintXml(toString()), Util.prettyPrintXml(process.toString())));
+        assertGeneralProperties(process);
+        assertInputValues(process);
+        assertOutputValues(process);
+        assertPropertiesInfo(process);
+        assertClustersEqual(getClusters().getClusters(), process.getClusters().getClusters());
+    }
+
+    /**
+     * Creates an empty process definition.
+     */
+    public static ProcessMerlin getEmptyProcess(ProcessMerlin process) {
+        ProcessMerlin draft = new ProcessMerlin(process.toString());
+        draft.setName("");
+        draft.setTags("");
+        draft.setACL(null);
+        draft.getInputs().getInputs().clear();
+        draft.getOutputs().getOutputs().clear();
+        draft.setRetry(null);
+        draft.clearProcessCluster();
+        draft.getProperties().getProperties().clear();
+        draft.setFrequency(null);
+        draft.setOrder(null);
+        draft.setTimezone(null);
+        draft.setParallel(0);
+        Workflow workflow = new Workflow();
+        workflow.setName(null);
+        workflow.setPath(null);
+        workflow.setVersion(null);
+        workflow.setEngine(null);
+        draft.setWorkflow(null, null, null);
+        return draft;
+    }
 }
 
 

http://git-wip-us.apache.org/repos/asf/falcon/blob/ff9c78e3/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
index 7c1f7ad..a1e3e2e 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
@@ -33,6 +33,7 @@ import org.openqa.selenium.support.ui.Select;
 import java.util.ArrayList;
 import java.util.List;
 
+
 /** Parent page object for all the search ui pages. */
 public abstract class AbstractSearchPage extends Page {
 

http://git-wip-us.apache.org/repos/asf/falcon/blob/ff9c78e3/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
index e429a60..e796ba0 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java
@@ -20,33 +20,79 @@ package org.apache.falcon.regression.ui.search;
 
 import com.google.common.collect.Lists;
 import org.apache.commons.lang.StringUtils;
+import org.apache.falcon.entity.v0.Frequency;
 import org.apache.falcon.entity.v0.process.ACL;
+import org.apache.falcon.entity.v0.process.Cluster;
+import org.apache.falcon.entity.v0.process.Clusters;
+import org.apache.falcon.entity.v0.process.EngineType;
+import org.apache.falcon.entity.v0.process.ExecutionType;
+import org.apache.falcon.entity.v0.process.Input;
+import org.apache.falcon.entity.v0.process.Inputs;
+import org.apache.falcon.entity.v0.process.Output;
+import org.apache.falcon.entity.v0.process.Outputs;
+import org.apache.falcon.entity.v0.process.PolicyType;
+import org.apache.falcon.entity.v0.process.Retry;
 import org.apache.falcon.entity.v0.process.Workflow;
+import org.apache.falcon.entity.v0.process.Validity;
 import org.apache.falcon.regression.Entities.ProcessMerlin;
 import org.apache.falcon.regression.core.util.UIAssert;
+import org.apache.log4j.Logger;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
 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.openqa.selenium.support.ui.ExpectedConditions;
 import org.openqa.selenium.support.ui.Select;
-import org.openqa.selenium.support.ui.WebDriverWait;
 import org.testng.Assert;
 
-import java.util.Arrays;
+import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.TimeZone;
 
 /** Page object of the Process creation page. */
 public class ProcessWizardPage extends AbstractSearchPage {
 
+    private static final Logger LOGGER = Logger.getLogger(ProcessWizardPage.class);
+
     @FindBys({
         @FindBy(className = "mainUIView"),
         @FindBy(className = "entityForm")
     })
     private WebElement processBox;
 
+    @FindBy(xpath = "//textarea[@ng-model='prettyXml']")
+    private WebElement processXml;
+
+    @FindBy(xpath = "//form[@name='processForm']/div[1]")
+    private WebElement summaryBox;
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "entityForm"),
+        @FindBy(className = "nextBtn")
+    })
+    private WebElement nextButton;
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "entityForm"),
+        @FindBy(className = "prevBtn")
+    })
+    private WebElement previousButton;
+
+    @FindBys({
+        @FindBy(id = "editXmlButton")
+    })
+    private WebElement editXmlButton;
+
+    @FindBy(xpath = "//a[contains(.,'Cancel')]")
+    private WebElement cancelButton;
+
+    @FindBy(xpath = "//div[contains(@class,'formBoxContainer')]")
+    private WebElement formBox;
+
     public ProcessWizardPage(WebDriver driver) {
         super(driver);
     }
@@ -56,15 +102,40 @@ public class ProcessWizardPage extends AbstractSearchPage {
         UIAssert.assertDisplayed(processBox, "Process box");
     }
 
-    private WebElement getNextButton() {
-        return driver.findElement(By.id("nextButton"));
+    /**
+     * Completes step 1 and clicks next.
+     */
+    public void goToPropertiesStep(ProcessMerlin process) {
+        setProcessGeneralInfo(process);
+        clickNext();
+
+    }
+
+    public void goToClustersStep(ProcessMerlin process) {
+        goToPropertiesStep(process);
+
+        setProcessPropertiesInfo(process);
+        clickNext();
+    }
+
+    public void clickNext() {
+        nextButton.click();
     }
 
-    public void pressNext() {
-        getNextButton().click();
+    public void clickPrevious(){
+        previousButton.click();
     }
 
-    /*----- Step1 elements & operations ----*/
+    public void clickCancel(){
+        cancelButton.click();
+    }
+
+    public void clickEditXml(){
+        editXmlButton.click();
+    }
+
+    /*----- Step1 General info ----*/
+
     private WebElement getName() {
         return driver.findElement(By.id("entityNameField"));
     }
@@ -104,28 +175,51 @@ public class ProcessWizardPage extends AbstractSearchPage {
         }
     }
 
-    public void setTags(List<String> tags) {
-        deleteTags();
-        //create enough number of tag fields
-        final int numTags = tags.size();
-        for (int i = 0; i < numTags - 1; i++) {
-            getAddTagButton().click();
+    private WebElement getTagKey(int index) {
+        return processBox.findElements(By.xpath("//input[@ng-model='tag.key']")).get(index);
+    }
+    private WebElement getTagValue(int index) {
+        return processBox.findElements(By.xpath("//input[@ng-model='tag.value']")).get(index);
+    }
+
+    public void setTagKey(int index, String tagKey){
+        getTagKey(index).sendKeys(tagKey);
+    }
+    public void setTagValue(int index, String tagValue){
+        getTagValue(index).sendKeys(tagValue);
+    }
+
+    public void setTags(String tagsStr){
+        if (StringUtils.isEmpty(tagsStr)){
+            return;
         }
-        final List<WebElement> tagTextFields = getTagTextFields();
-        Assert.assertEquals(tagTextFields.size() % 2, 0,
-            "Number of text fields for tags should be even, found: " + tagTextFields.size());
-        for (int i = 0; i < (tagTextFields.size() / 2); i++) {
-            final String oneTag = tags.get(i);
-            final String[] tagParts = oneTag.split("=");
-            Assert.assertEquals(tagParts.length, 2,
-                "Each tag is expected to be of form key=value, found: " + oneTag);
-            String key = tagParts[0];
-            String val = tagParts[1];
-            tagTextFields.get(2 * i).sendKeys(key);
-            tagTextFields.get(2 * i + 1).sendKeys(val);
+        String[] tags = tagsStr.split(",");
+        for (int i = 0; i < tags.length; i++){
+            String[] keyValue = tags[i].split("=");
+            setTagKey(i, keyValue[0]);
+            setTagValue(i, keyValue[1]);
+            if (tags.length > i + 1){
+                getAddTagButton().click();
+            }
         }
     }
 
+    public String getTagKeyText(int index){
+        return getTagKey(index).getAttribute("value");
+    }
+
+    public String getTagValueText(int index){
+        return getTagValue(index).getAttribute("value");
+    }
+
+    public boolean isPigRadioSelected(){
+        return getPigRadio().isSelected();
+    }
+
+    public String getEngineVersionText(){
+        return getEngineVersion().getFirstSelectedOption().getAttribute("value");
+    }
+
     private WebElement getWfName() {
         return driver.findElement(By.id("workflowNameField"));
     }
@@ -168,6 +262,7 @@ public class ProcessWizardPage extends AbstractSearchPage {
             Assert.fail("Unexpected workflow engine: " + processWf.getEngine());
         }
         final String version = processWf.getVersion();
+        // The getVersion() method returns '1.0' if its null, hence the hack below
         if (StringUtils.isNotEmpty(version) && !version.equals("1.0")) {
             getEngineVersion().selectByVisibleText(version);
         }
@@ -200,24 +295,665 @@ public class ProcessWizardPage extends AbstractSearchPage {
         aclPerm.sendKeys(acl.getPermission());
     }
 
-    public void doStep1(ProcessMerlin process) {
+    public void setProcessGeneralInfo(ProcessMerlin process) {
         setName(process.getName());
         final String tags = StringUtils.trimToEmpty(process.getTags());
-        setTags(Arrays.asList(tags.split(",")));
+        setTags(tags);
         setWorkflow(process.getWorkflow());
         setAcl(process.getACL());
-        final WebElement step1Element = getName();
-        pressNext();
-        new WebDriverWait(driver, AbstractSearchPage.PAGELOAD_TIMEOUT_THRESHOLD).until(
-            ExpectedConditions.stalenessOf(step1Element));
     }
 
-    /*----- Step2 elements & operations ----*/
+    public void isFrequencyQuantityDisplayed(boolean isDisplayed) {
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getFrequencyQuantity(), "Frequency Quantity");
+        }else {
+            try{
+                getFrequencyQuantity();
+                Assert.fail("Frequency Quantity found");
+            } catch (Exception ex){
+                LOGGER.info("Frequency Quantity not found");
+            }
+        }
+    }
+
+    public void isValidityStartDateDisplayed(boolean isDisplayed) {
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getStartDate(), "Cluster Validity Start Date");
+        }else {
+            try{
+                getStartDate();
+                Assert.fail("Cluster Validity Start Date found");
+            } catch (Exception ex){
+                LOGGER.info("Cluster Validity Start Date not found");
+            }
+        }
+    }
+
+    public void isAddInputButtonDisplayed(boolean isDisplayed) {
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getAddInputButton(), "Add Input button.");
+        }else {
+            try{
+                getAddInputButton();
+                Assert.fail("Add Input Button found");
+            } catch (Exception ex){
+                LOGGER.info("Add Input Button not found");
+            }
+        }
+    }
+
+    public void isSaveButtonDisplayed(boolean isDisplayed) {
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getSaveProcessButton(), "Save Button");
+        }else {
+            try{
+                getSaveProcessButton();
+                Assert.fail("Save Process Button found");
+            } catch (Exception ex){
+                LOGGER.info("Save Process Button not found");
+            }
+        }
+    }
+
+    private WebElement getSaveProcessButton(){
+        return formBox.findElement(By.xpath("//button[contains(.,'Save')]"));
+    }
+
+    public void isTagsDisplayed(int index, boolean isDisplayed){
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getTagKey(index), "Tag Key Index - " + index);
+            UIAssert.assertDisplayed(getTagValue(index), "Tag Value Index - " + index);
+        }else{
+            try{
+                getTagKey(index);
+                Assert.fail("Tag Key Index - " + index + " found");
+            } catch (Exception ex){
+                LOGGER.info("Tag Key Index - " + index + " not found");
+            }
+            try{
+                getTagValue(index);
+                Assert.fail("Tag Key Value - " + index + " found");
+            } catch (Exception ex){
+                LOGGER.info("Tag Key Value - " + index + " not found");
+            }
+        }
+    }
+
+    /*----- Step2 Properties ----*/
+
     private Select getTimezone() {
-        return new Select(driver.findElement(By.id("timeZoneSelect")));
+        return new Select(formBox.findElement(By.xpath("//select[contains(@class, 'TZSelect')]")));
     }
 
     public void setTimezone(TimeZone timezone) {
-        getTimezone().selectByValue(timezone.getDisplayName());
+        if (timezone == null) {
+            return;
+        }
+        String timeZone = timezone.getID();
+        getTimezone().selectByValue(timeZone);
+    }
+
+    private WebElement getFrequencyQuantity() {
+        return processBox.findElement(By.xpath("//input[@ng-model='process.frequency.quantity']"));
+    }
+    private Select getFrequencyUnit() {
+        return new Select(processBox.findElement(By.xpath(
+            "//select[@ng-model='process.frequency.unit']")));
+    }
+
+    public String getFrequencyQuantityText(){
+        return getFrequencyQuantity().getAttribute("value");
+    }
+
+    public String getMaxParallelInstancesText(){
+        return getMaxParallelInstances().getFirstSelectedOption().getAttribute("value");
+    }
+
+    public String getTimezoneText(){
+        return getTimezone().getFirstSelectedOption().getAttribute("value");
+    }
+
+    public String getOrderText(){
+        return getOrder().getFirstSelectedOption().getAttribute("value");
+    }
+
+    public void setFrequencyQuantity(String frequencyQuantity){
+        getFrequencyQuantity().sendKeys(frequencyQuantity);
+    }
+    public void setFrequencyUnit(String frequencyUnit){
+        getFrequencyUnit().selectByVisibleText(frequencyUnit);
+    }
+
+    public List<String> getTimezoneValues(){
+        return getDropdownValues(getTimezone());
+    }
+
+    public List<String> getFrequencyUnitValues(){
+        return getDropdownValues(getFrequencyUnit());
+    }
+
+    public List<String> getMaxParallelInstancesValues(){
+        return getDropdownValues(getMaxParallelInstances());
+    }
+
+    public List<String> getOrderValues(){
+        return getDropdownValues(getOrder());
+    }
+
+    public List<String> getRetryPolicyValues(){
+        return getDropdownValues(getRetryPolicy());
+    }
+
+    public List<String> getRetryDelayUnitValues(){
+        return getDropdownValues(getRetryDelayUnit());
+    }
+
+    private Select getMaxParallelInstances(){
+        return new Select(formBox.findElement(By.xpath("//select[@ng-model='process.parallel']")));
+    }
+
+    public void setMaxParallelInstances(int quantity) {
+        getMaxParallelInstances().selectByValue(String.valueOf(quantity));
+    }
+
+    private Select getOrder(){
+        return new Select(formBox.findElement(By.xpath("//select[@ng-model='process.order']")));
+    }
+
+    public void setOrder(ExecutionType order) {
+        getOrder().selectByValue(order.value());
+    }
+
+    private Select getRetryPolicy(){
+        return new Select(formBox.findElement(By.xpath("//select[@ng-model='process.retry.policy']")));
+    }
+
+    private Select getRetryDelayUnit(){
+        return new Select(formBox.findElement(By.xpath("//select[@ng-model='process.retry.delay.unit']")));
+    }
+
+    private WebElement getAttempts(){
+        return formBox.findElement(By.id("attemptsField"));
+    }
+
+    private WebElement getDelayQuantity(){
+        return formBox.findElement(By.id("delayQuantity"));
+    }
+
+    public void setRetry(Retry retry) {
+        getRetryPolicy().selectByValue(retry.getPolicy().value());
+        getAttempts().sendKeys(String.valueOf(retry.getAttempts()));
+        getDelayQuantity().sendKeys(retry.getDelay().getFrequency());
+        getRetryDelayUnit().selectByValue(retry.getDelay().getTimeUnit().name());
+    }
+
+    /**
+     * Enter process info on Page 2 of processSetup Wizard.
+     */
+    public void setProcessPropertiesInfo(ProcessMerlin process) {
+        setTimezone(process.getTimezone());
+        setFrequencyQuantity(process.getFrequency().getFrequency());
+        setFrequencyUnit(process.getFrequency().getTimeUnit().toString());
+        setMaxParallelInstances(process.getParallel());
+        setOrder(process.getOrder());
+        setRetry(process.getRetry());
+    }
+
+    /*-----Step3 Clusters-------*/
+
+    public WebElement getStartDate() {
+        List<WebElement> inputs = driver.findElements(
+            By.xpath("//input[contains(@ng-model, 'cluster.validity.start.date')]"));
+        return inputs.get(inputs.size() - 1);
+    }
+
+    public WebElement getEndDate() {
+        List<WebElement> inputs = formBox.findElements(
+            By.xpath("//input[contains(@ng-model, 'cluster.validity.end.date')]"));
+        return inputs.get(inputs.size() - 1);
+    }
+
+    public String getValidityEnd() {
+        return String.format("%s %s:%s", getEndDate().getAttribute("value"), getEndHours().getAttribute("value"),
+            getEndMinutes().getAttribute("value"));
+    }
+
+    public WebElement getStartHours() {
+        List<WebElement> inputs = formBox.findElements(By.xpath("//input[contains(@ng-model,
'hours')]"));
+        return inputs.get(inputs.size() - 2);
+    }
+
+    public WebElement getEndHours() {
+        List<WebElement> inputs = formBox.findElements(By.xpath("//input[contains(@ng-model,
'hours')]"));
+        return inputs.get(inputs.size() - 1);
+    }
+
+    public WebElement getStartMinutes() {
+        List<WebElement> inputs = formBox.findElements(By.xpath("//input[contains(@ng-model,
'minutes')]"));
+        return inputs.get(inputs.size() - 2);
+    }
+
+    public WebElement getEndMinutes() {
+        List<WebElement> inputs = formBox.findElements(By.xpath("//input[contains(@ng-model,
'minutes')]"));
+        return inputs.get(inputs.size() - 1);
+    }
+
+    public WebElement getStartMeredian() {
+        List<WebElement> buttons = formBox.findElements(By.xpath("//td[@ng-show='showMeridian']/button"));
+        return buttons.get(buttons.size() - 2);
+    }
+
+    public WebElement getEndMeredian() {
+        List<WebElement> buttons = formBox.findElements(By.xpath("//td[@ng-show='showMeridian']/button"));
+        return buttons.get(buttons.size() - 1);
+    }
+
+    /**
+     * Retrieves the last cluster select.
+     */
+    public Select getClusterSelect() {
+        List<WebElement> selects = formBox.findElements(By.xpath("//select[contains(@ng-model,
'cluster.name')]"));
+        return new Select(selects.get(selects.size() - 1));
+    }
+
+    public void clickAddClusterButton() {
+        int initialSize = getWizardClusterCount();
+        formBox.findElement(By.xpath("//button[contains(., 'add cluster')]")).click();
+        int finalSize = getWizardClusterCount();
+        Assert.assertEquals(finalSize - initialSize, 1, "New cluster block should been added.");
+    }
+
+    /**
+     * Removes last cluster on the form.
+     */
+    public void deleteLastCluster() {
+        int initialSize = getWizardClusterCount();
+        List<WebElement> buttons = formBox.findElements(By.xpath("//button[contains(.,
'delete')]"));
+        Assert.assertTrue(buttons.size() > 0,
+            "Delete button should be present. There should be at least 2 cluster blocks");
+        buttons.get(buttons.size() - 1).click();
+        int finalSize = getWizardClusterCount();
+        Assert.assertEquals(initialSize - finalSize, 1, "One cluster block should been removed.");
+    }
+
+    /**
+     * Sets multiple clusters in process.
+     */
+    public void setClusters(Clusters clusters) {
+        for (int i = 0; i < clusters.getClusters().size(); i++) {
+            if (i > 0) {
+                clickAddClusterButton();
+            }
+            setCluster(clusters.getClusters().get(i));
+        }
+    }
+
+    /**
+     * Fills the last cluster on the form.
+     */
+    public void setCluster(Cluster cluster) {
+        selectCluster(cluster.getName());
+        setClusterValidity(cluster);
+    }
+
+    /**
+     * Populates cluster form with values from process.Cluster object.
+     * @param cluster process process.Cluster object
+     */
+    public void setClusterValidity(Cluster cluster) {
+        SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy-hh-mm-a");
+        String start = format.format(cluster.getValidity().getStart());
+        String [] parts = start.split("-");
+        getStartDate().clear();
+        sendKeysSlowly(getStartDate(), parts[0]);
+        getStartHours().clear();
+        sendKeysSlowly(getStartHours(), parts[1]);
+        getStartMinutes().clear();
+        sendKeysSlowly(getStartMinutes(), parts[2]);
+        String meredian = getStartMeredian().getText();
+        if (!meredian.equals(parts[3])) {
+            getStartMeredian().click();
+        }
+        String end = format.format(cluster.getValidity().getEnd());
+        parts = end.split("-");
+        getEndDate().clear();
+        sendKeysSlowly(getEndDate(), parts[0]);
+        getEndHours().clear();
+        sendKeysSlowly(getEndHours(), parts[1]);
+        getEndMinutes().clear();
+        sendKeysSlowly(getEndMinutes(), parts[2]);
+        meredian = getEndMeredian().getText();
+        if (!meredian.equals(parts[3])) {
+            getEndMeredian().click();
+        }
+    }
+
+    public void selectCluster(String clusterName) {
+        getClusterSelect().selectByValue(clusterName);
+    }
+
+    public String getClusterName(int indx) {
+        List<WebElement> blocks = formBox.findElements(By.xpath("//div[contains(@class,
'processCluster')]"));
+        return new Select(blocks.get(indx).findElement(By.tagName("select")))
+            .getFirstSelectedOption().getText();
+    }
+
+    public int getWizardClusterCount() {
+        return formBox.findElements(By.xpath("//div[contains(@class, 'processCluster')]")).size();
+    }
+
+    public void setProcessClustersInfo(ProcessMerlin process) {
+        for (int i = 0; i < process.getClusters().getClusters().size(); i++) {
+            if (i >= 1) {
+                clickAddClusterButton();
+            }
+            setCluster(process.getClusters().getClusters().get(i));
+        }
+    }
+
+    public List<String> getClustersFromDropDown() {
+        return getDropdownValues(getClusterSelect());
+    }
+
+    public void clickOnValidityStart() {
+        getStartDate().click();
+        List<WebElement> calendars = formBox.findElements(By.xpath("//ul[@ng-model='date']"));
+        waitForAngularToFinish();
+        Assert.assertTrue(calendars.get(calendars.size() - 2).isDisplayed(), "Calendar should
pop up.");
+    }
+
+    public void clickOnValidityEnd() {
+        getEndDate().click();
+        List<WebElement> calendars = formBox.findElements(By.xpath("//ul[@ng-model='date']"));
+        waitForAngularToFinish();
+        Assert.assertTrue(calendars.get(calendars.size() - 1).isDisplayed(), "Calendar should
pop up.");
+    }
+
+    /* Step 4 - Inputs & Outputs*/
+
+    private WebElement getAddInputButton() {
+        return formBox.findElement(By.xpath("//button[contains(., 'add input')]"));
+    }
+
+    private WebElement getAddOutputButton() {
+        return formBox.findElement(By.xpath("//button[contains(., 'add output')]"));
+    }
+
+    private WebElement getDeleteInputButton() {
+        return formBox.findElement(By.xpath("//button[contains(., 'delete')]"));
+    }
+
+    private WebElement getInputName(int index) {
+        return formBox.findElements(By.xpath("//input[@ng-model='input.name']")).get(index);
+    }
+
+    private Select getInputFeed(int index) {
+        return new Select(formBox.findElements(By.xpath("//select[@ng-model='input.feed']")).get(index));
+    }
+
+    private WebElement getInputStart(int index) {
+        return formBox.findElements(By.xpath("//input[@ng-model='input.start']")).get(index);
+    }
+
+    private WebElement getInputEnd(int index) {
+        return formBox.findElements(By.xpath("//input[@ng-model='input.end']")).get(index);
+    }
+
+    public void setInputInfo(Inputs inputs){
+        for (int i = 0; i < inputs.getInputs().size(); i++) {
+            clickAddInput();
+            sendKeysSlowly(getInputName(i), inputs.getInputs().get(i).getName());
+            getInputFeed(i).selectByVisibleText(inputs.getInputs().get(i).getFeed());
+            sendKeysSlowly(getInputStart(i), inputs.getInputs().get(i).getStart());
+            sendKeysSlowly(getInputEnd(i), inputs.getInputs().get(i).getEnd());
+        }
+    }
+
+    public void clickAddInput(){
+        getAddInputButton().click();
+    }
+
+    public void clickAddOutput(){
+        getAddOutputButton().click();
+    }
+
+    public void clickDeleteInput(){
+        getDeleteInputButton().click();
+    }
+
+    private WebElement getDeleteOutputButton() {
+        return formBox.findElement(By.xpath("//button[contains(., 'delete')]"));
+    }
+
+    private WebElement getOutputName(int index) {
+        return formBox.findElements(By.xpath("//input[@ng-model='output.name']")).get(index);
+    }
+
+    private Select getOutputFeed(int index) {
+        return new Select(formBox.findElements(By.xpath("//select[@ng-model='output.feed']")).get(index));
+    }
+
+    private WebElement getOutputInstance(int index) {
+        return formBox.findElements(By.xpath("//input[@ng-model='output.outputInstance']")).get(index);
+    }
+
+    public void clickDeleteOutput(){
+        getDeleteOutputButton().click();
+    }
+
+    public void setOutputInfo(Outputs outputs){
+        for (int i = 0; i < outputs.getOutputs().size(); i++) {
+            clickAddOutput();
+            sendKeysSlowly(getOutputName(i), outputs.getOutputs().get(i).getName());
+            getOutputFeed(i).selectByVisibleText(outputs.getOutputs().get(i).getFeed());
+            sendKeysSlowly(getOutputInstance(i), outputs.getOutputs().get(i).getInstance());
+        }
+    }
+
+    public void setInputOutputInfo(ProcessMerlin process){
+        setInputInfo(process.getInputs());
+        setOutputInfo(process.getOutputs());
+    }
+
+    public List<String> getInputValues(int index){
+        return getDropdownValues(getInputFeed(index));
+    }
+
+    public List<String> getOutputValues(int index){
+        return getDropdownValues(getOutputFeed(index));
+    }
+
+    public String getInputNameText(int index){
+        return getInputName(index).getAttribute("value");
+    }
+
+    public String getInputFeedText(int index){
+        return getInputFeed(index).getFirstSelectedOption().getAttribute("value");
+    }
+
+    public String getInputStartText(int index){
+        return getInputStart(index).getAttribute("value");
+    }
+
+    public String getInputEndText(int index){
+        return getInputEnd(index).getAttribute("value");
+    }
+
+    public String getOutputNameText(int index){
+        return getOutputName(index).getAttribute("value");
+    }
+
+    public String getOutputFeedText(int index){
+        return getOutputFeed(index).getFirstSelectedOption().getAttribute("value");
+    }
+
+    public String getOutputInstanceText(int index){
+        return getOutputInstance(index).getAttribute("value");
+    }
+
+    public void isInputNameDisplayed(int index, boolean isDisplayed) {
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getInputName(index), "Input Name " + index);
+        }else {
+            try{
+                getInputName(index);
+                Assert.fail("Input Name " + index + " found");
+            } catch (Exception ex){
+                LOGGER.info("Input Name " + index + " not found");
+            }
+        }
+    }
+
+    public void isOutputNameDisplayed(int index, boolean isDisplayed) {
+        if (isDisplayed){
+            UIAssert.assertDisplayed(getOutputName(index), "Output Name " + index);
+        }else {
+            try{
+                getOutputName(index);
+                Assert.fail("Output Name " + index + " found");
+            } catch (Exception ex){
+                LOGGER.info("Output Name " + index + " not found");
+            }
+        }
+    }
+
+
+    /* Step 5 - Summary */
+
+    public void clickSave(){
+        getSaveProcessButton().click();
+    }
+
+    /**
+     * Creates ProcessMerlin object from xml preview string.
+     */
+    public ProcessMerlin getProcessMerlinFromProcessXml() throws Exception{
+        waitForAngularToFinish();
+        return new ProcessMerlin(processXml.getAttribute("value"));
+    }
+
+    /**
+     * Pushes xml string to xml preview.
+     */
+    public void setProcessXml(String xml) throws Exception{
+        processXml.clear();
+        processXml.sendKeys(xml);
+    }
+
+    /**
+     * Method gets text from summary box and parses it to ProcessMerlin object.
+     * @param draft empty ProcessMerlin object
+     */
+    public ProcessMerlin getProcessFromSummaryBox(ProcessMerlin draft) {
+        String text = summaryBox.getText().trim();
+        draft.setName(getProperty(text, null, "Tags", 2));
+        String currentBlock = text.substring(text.indexOf("Tags"), text.indexOf("Workflow"));
+        String [] parts;
+        parts = currentBlock.trim().split("\\n");
+        String tags = "";
+        for (int i = 1; i < parts.length; i++) {
+            String tag = parts[i];
+            if (!tag.contains("No tags")) {
+                tag = tag.replace(" ", "");
+                tags = tags + (tags.isEmpty() ? tag : "," + tag);
+            }
+        }
+        if (!tags.isEmpty()) {
+            draft.setTags(tags);
+        }
+        Workflow workflow = new Workflow();
+        workflow.setName(getProperty(text, "Workflow", "Engine", 2));
+        workflow.setEngine(EngineType.fromValue(getProperty(text, "Engine", "Version", 1)));
+        workflow.setVersion(getProperty(text, "Version", "Path", 1));
+        workflow.setPath(getProperty(text, "Path", "Timing", 1));
+        draft.setWorkflow(workflow);
+
+        draft.setTimezone(TimeZone.getTimeZone(getProperty(text, "Timing", "Frequency", 2)));
+        parts = getProperty(text, "Frequency", "Max. parallel instances", 1).split(" ");
+        draft.setFrequency(new Frequency(parts[1], Frequency.TimeUnit.valueOf(parts[2])));
+        draft.setParallel(Integer.parseInt(getProperty(text, "Max. parallel instances", "Order",
1)));
+        draft.setOrder(ExecutionType.fromValue(getProperty(text, "Order", "Retry", 1)));
+
+        Retry retry = new Retry();
+        retry.setPolicy(PolicyType.fromValue(getProperty(text, "Retry", "Attempts", 2)));
+        retry.setAttempts(Integer.parseInt(getProperty(text, "Attempts", "Delay", 1)));
+        parts = getProperty(text, "Delay", "Clusters", 1).split(" ");
+        retry.setDelay(new Frequency(parts[2], Frequency.TimeUnit.valueOf(parts[3])));
+        draft.setRetry(retry);
+
+        //get clusters
+        currentBlock = text.substring(text.indexOf("Clusters"), text.indexOf("Inputs"));
+        int last = 0;
+        while (last != -1) {
+            Cluster cluster = new Cluster();
+            cluster.setName(getProperty(currentBlock, "Name", "Validity", 1));
+            //remove the part which was used
+            currentBlock = currentBlock.substring(currentBlock.indexOf("Validity"));
+            //get validity
+            String start = getProperty(currentBlock, "Validity", "End", 2).split(" ")[1];
+            //check if there are other clusters
+            last = currentBlock.indexOf("Name");
+            String innerBlock = currentBlock.substring(currentBlock.indexOf("End"),
+                last != -1 ? last : currentBlock.length() - 1).trim();
+            parts = innerBlock.trim().split("\\n");
+            String end = parts[1].split(" ")[1];
+            Validity validity = new Validity();
+            DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'");
+            validity.setStart(formatter.parseDateTime(start.replaceAll("\"", "")).toDate());
+            validity.setEnd(formatter.parseDateTime(end.replaceAll("\"", "")).toDate());
+            cluster.setValidity(validity);
+            draft.getClusters().getClusters().add(cluster);
+        }
+        //get inputs
+        currentBlock = text.substring(text.indexOf("Inputs"), text.indexOf("Outputs"));
+        last = 0;
+        while (last != -1) {
+            Input input = new Input();
+            //get input name
+            input.setName(getProperty(currentBlock, "Name", "Feed", 1));
+            //remove the part which was used
+            currentBlock = currentBlock.substring(currentBlock.indexOf("Name") + 4);
+            //get input feed
+            input.setFeed(getProperty(currentBlock, "Feed", "Instance", 1));
+            //get input start
+            input.setStart(getProperty(currentBlock, "Instance", "End", 2));
+            //get input end
+            last = currentBlock.indexOf("Name");
+            String innerBlock = currentBlock.substring(currentBlock.indexOf("End"),
+                last != -1 ? last : currentBlock.length() - 1).trim();
+            parts = innerBlock.trim().split("\\n");
+            input.setEnd(parts[1]);
+            draft.getInputs().getInputs().add(input);
+            //remove part which was parsed
+            currentBlock = currentBlock.substring(currentBlock.indexOf("End") + 4);
+        }
+        //get outputs
+        currentBlock = text.substring(text.indexOf("Outputs"));
+        last = 0;
+        while (last != -1) {
+            Output output = new Output();
+            output.setName(getProperty(currentBlock, "Name", "Feed", 1));
+            //remove the part which was used
+            currentBlock = currentBlock.substring(currentBlock.indexOf("Feed"));
+            //get feed
+            output.setFeed(getProperty(currentBlock, "Feed", "Instance", 1));
+            last = currentBlock.indexOf("Name");
+            output.setInstance(getProperty(currentBlock, "Instance", "Name", 2));
+            draft.getOutputs().getOutputs().add(output);
+        }
+        return draft;
+    }
+
+    /**
+     * Retrieves property from source text.
+     */
+    private String getProperty(String block, String start, String end, int propertyIndex)
{
+        int s = start != null ? block.indexOf(start) : 0;
+        s = s == -1 ? 0 : s;
+        int e = end != null ? block.indexOf(end) : block.length() - 1;
+        e = e == -1 ? block.length() : e;
+        String subBlock = block.substring(s, e).trim();
+        String [] parts = subBlock.trim().split("\\n");
+        return parts.length - 1 >= propertyIndex ? parts[propertyIndex].trim() : null;
     }
 }


Mime
View raw message