You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by ra...@apache.org on 2015/06/04 20:53:00 UTC
[1/2] falcon git commit: FALCON-1249 Tests for process setup wizard
conributed by Namit Maheshwari and Paul Isaychuk
Repository: falcon
Updated Branches:
refs/heads/master 8ee6d45f0 -> ff9c78e3c
http://git-wip-us.apache.org/repos/asf/falcon/blob/ff9c78e3/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
index 4e1474c..7852390 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java
@@ -18,11 +18,14 @@
package org.apache.falcon.regression.searchUI;
-import org.apache.commons.lang.StringUtils;
import org.apache.falcon.entity.v0.Frequency;
+import org.apache.falcon.entity.v0.process.*;
+import org.apache.falcon.regression.Entities.ClusterMerlin;
import org.apache.falcon.regression.Entities.ProcessMerlin;
import org.apache.falcon.regression.core.bundle.Bundle;
import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.falcon.regression.core.response.ServiceResponse;
+import org.apache.falcon.regression.core.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.HadoopUtil;
import org.apache.falcon.regression.core.util.OSUtil;
@@ -30,29 +33,68 @@ import org.apache.falcon.regression.testHelper.BaseUITestClass;
import org.apache.falcon.regression.ui.search.LoginPage;
import org.apache.falcon.regression.ui.search.ProcessWizardPage;
import org.apache.falcon.regression.ui.search.SearchPage;
-import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.log4j.Logger;
-import org.apache.oozie.client.OozieClient;
+import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import javax.xml.bind.JAXBException;
import java.io.IOException;
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
import java.util.List;
+import java.util.TimeZone;
/** UI tests for process creation. */
@Test(groups = "search-ui")
public class ProcessSetupTest extends BaseUITestClass {
private static final Logger LOGGER = Logger.getLogger(ProcessSetupTest.class);
private final ColoHelper cluster = servers.get(0);
- private final FileSystem clusterFS = serverFS.get(0);
- private final OozieClient clusterOC = serverOC.get(0);
private String baseTestHDFSDir = cleanAndGetTestDir();
private String aggregateWorkflowDir = baseTestHDFSDir + "/aggregator";
private String feedInputPath = baseTestHDFSDir + "/input" + MINUTE_DATE_PATTERN;
private String feedOutputPath = baseTestHDFSDir + "/output" + MINUTE_DATE_PATTERN;
private ProcessWizardPage processWizardPage = null;
+ private final List<String> timeZones = new ArrayList<>(Arrays.asList(
+ "-Select timezone-", "UTC", "(GMT -12:00) Eniwetok, Kwajalein",
+ "(GMT -11:00) Midway Island, Samoa", "(GMT -10:00) Hawaii", "(GMT -9:00) Alaska",
+ "(GMT -8:00) Pacific Time (US & Canada)", "(GMT -7:00) Mountain Time (US & Canada)",
+ "(GMT -6:00) Central Time (US & Canada), Mexico City",
+ "(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima",
+ "(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz", "(GMT -3:30) Newfoundland",
+ "(GMT -3:00) Brazil, Buenos Aires, Georgetown", "(GMT -2:00) Mid-Atlantic",
+ "(GMT -1:00 hour) Azores, Cape Verde Islands",
+ "(GMT) Western Europe Time, London, Lisbon, Casablanca",
+ "(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris",
+ "(GMT +2:00) Kaliningrad, South Africa",
+ "(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg", "(GMT +3:30) Tehran",
+ "(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi", "(GMT +4:30) Kabul",
+ "(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent",
+ "(GMT +5:30) Bombay, Calcutta, Madras, New Delhi", "(GMT +5:45) Kathmandu",
+ "(GMT +6:00) Almaty, Dhaka, Colombo", "(GMT +7:00) Bangkok, Hanoi, Jakarta",
+ "(GMT +8:00) Beijing, Perth, Singapore, Hong Kong",
+ "(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk", "(GMT +9:30) Adelaide, Darwin",
+ "(GMT +10:00) Eastern Australia, Guam, Vladivostok",
+ "(GMT +11:00) Magadan, Solomon Islands, New Caledonia",
+ "(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka"
+ ));
+
+ private final List<String> timeUnits = new ArrayList<>(Arrays.asList("minutes", "hours", "days", "months"));
+ private final List<String> delayTimeUnits = new ArrayList<>(Arrays.asList("-Select delay-", "minutes",
+ "hours", "days", "months"));
+ private final List<String> parallel = new ArrayList<>(Arrays.asList("1", "2", "3", "4", "5", "6", "7",
+ "8", "9", "10", "11", "12"));
+ private final List<String> order = new ArrayList<>(Arrays.asList("-Select order-", "FIFO", "LIFO", "LAST_ONLY"));
+ private final List<String> policy =new ArrayList<>(Arrays.asList("-Select policy-", "periodic", "exp-backoff",
+ "final"));
+
+ private ProcessMerlin process;
@BeforeMethod(alwaysRun = true)
public void setup() throws IOException {
@@ -74,6 +116,10 @@ public class ProcessSetupTest extends BaseUITestClass {
SearchPage searchPage = loginPage.doDefaultLogin();
processWizardPage = searchPage.getPageHeader().doCreateProcess();
processWizardPage.checkPage();
+ process = bundles[0].getProcessObject();
+ //we need to reduce name size to 39 symbols
+ process.setName(process.getName().substring(0, 39));
+ process.setTags("first=yes,second=yes,third=no");
}
@AfterMethod(alwaysRun = true)
@@ -82,6 +128,8 @@ public class ProcessSetupTest extends BaseUITestClass {
closeBrowser();
}
+ /* Step 1 tests */
+
/**
* Test header of the EntityPage.
* Check that buttons (logout, entities, uploadXml, help, Falcon) are present, and names are
@@ -99,13 +147,929 @@ public class ProcessSetupTest extends BaseUITestClass {
/**
* Populate fields with valid values (name, tag, workflow, engine, version, wf path)
* and check that user can go to the next step.
+ * @throws Exception
*/
@Test
public void testGeneralStepDefaultScenario() throws Exception {
- final ProcessMerlin process = bundles[0].getProcessObject();
- final List<String> tags = Arrays.asList("first=yes", "second=yes", "third=yes", "wrong=no");
- process.setTags(StringUtils.join(tags, ","));
- processWizardPage.doStep1(process);
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Assert on the click of next, the Page moves to the next page
+ processWizardPage.isFrequencyQuantityDisplayed(true);
+ }
+
+ /**
+ * Populate fields with valid values (name, tag, workflow, engine, version, wf path)
+ * Check that they are reflected on XML preview.
+ * @throws Exception
+ */
+ @Test
+ public void testGeneralStepXmlPreview() throws Exception{
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+
+ // Get process from XML Preview
+ ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+
+ // Assert all the values entered on the General Info Page
+ LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
+ process.assertGeneralProperties(processFromXML);
+ }
+
+ /**
+ * Add few tags to the process. Click edit XML. Remove both tags from XML.
+ * Check that properties were removed from matching fields.
+ * Now click Edit XML again. Add new tag, Pig engine (instead of Oozie) with one of existing versions to the XML.
+ * Check that changes have been reflected on wizard page.
+ * @throws Exception
+ */
+ @Test
+ public void testGeneralStepEditXml() throws Exception{
+
+ // Set tag in process
+ process.setTags("first=yes,second=yes");
+
+ // Set tag and group on the Wizard
+ processWizardPage.setTags(process.getTags());
+
+ // Get XML, and set tag and group back to null
+ ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ processFromXML.setTags(null);
+
+ // Now click EditXML and set the updated XML here
+ processWizardPage.clickEditXml();
+ String xmlToString = processFromXML.toString();
+ processWizardPage.setProcessXml(xmlToString);
+ processWizardPage.clickEditXml();
+
+ Thread.sleep(1000);
+ // Assert that there is only one Tag on the Wizard window
+ processWizardPage.isTagsDisplayed(0, true);
+ processWizardPage.isTagsDisplayed(1, false);
+
+ // Assert that the Tag value is empty on the Wizard window
+ Assert.assertEquals(processWizardPage.getTagKeyText(0), "",
+ "Tag Key Should be empty on the Wizard window");
+ Assert.assertEquals(processWizardPage.getTagValueText(0), "",
+ "Tag Value Should be empty on the Wizard window");
+
+ // Set Tag and Engine values
+ processFromXML.setTags("third=yes,fourth=no");
+ processFromXML.getWorkflow().setEngine(EngineType.PIG);
+ processFromXML.getWorkflow().setVersion("pig-0.13.0");
+
+ // Now click EditXML and set the updated XML here
+ processWizardPage.clickEditXml();
+ xmlToString = processFromXML.toString();
+ processWizardPage.setProcessXml(xmlToString);
+ processWizardPage.clickEditXml();
+
+ // Assert that there are two Tags on the Wizard window
+ processWizardPage.isTagsDisplayed(0, true);
+ processWizardPage.isTagsDisplayed(1, true);
+
+ // Assert that the Tag values are correct on the Wizard window
+ Assert.assertEquals(processWizardPage.getTagKeyText(0), "third",
+ "Unexpected Tag1 Key on the Wizard window");
+ Assert.assertEquals(processWizardPage.getTagValueText(0), "yes",
+ "Unexpected Tag1 Value on the Wizard window");
+ Assert.assertEquals(processWizardPage.getTagKeyText(1), "fourth",
+ "Unexpected Tag2 Key on the Wizard window");
+ Assert.assertEquals(processWizardPage.getTagValueText(1), "no",
+ "Unexpected Tag2 Value on the Wizard window");
+ Assert.assertEquals(processWizardPage.isPigRadioSelected(), true,
+ "Unexpected Engine on the Wizard window");
+ Assert.assertTrue(processWizardPage.getEngineVersionText().contains("pig-0.13.0"),
+ "Unexpected Engine Version on the Wizard window");
+ }
+
+ /**
+ * Add two tags to the process. Check that it is present.
+ * Delete the tag. Check that it has been removed.
+ * @throws Exception
+ */
+ @Test
+ public void testGeneralStepAddRemoveTag() throws Exception{
+
+ // Set tag in process
+ process.setTags("first=yes,second=yes");
+
+ // Set tag and group on the Wizard
+ processWizardPage.setTags(process.getTags());
+
+ // Assert that there are two Tags on the Wizard window
+ processWizardPage.isTagsDisplayed(0, true);
+ processWizardPage.isTagsDisplayed(1, true);
+
+ // Delete the tags
+ processWizardPage.deleteTags();
+
+ // Assert that there is only one Tag on the Wizard window
+ processWizardPage.isTagsDisplayed(0, true);
+ processWizardPage.isTagsDisplayed(1, false);
+
+ // Assert that the Tag value is empty on the Wizard window
+ Assert.assertEquals(processWizardPage.getTagKeyText(0), "",
+ "Tag Key Should be empty on the Wizard window");
+ Assert.assertEquals(processWizardPage.getTagValueText(0), "",
+ "Tag Value Should be empty on the Wizard window");
+ }
+
+ /* Step 2 tests */
+
+ /**
+ * Populate all fields with valid values (frequency, parallel, retry).
+ * Check that user can go to the next step.
+ * @throws Exception
+ */
+ @Test
+ public void testTimingStepDefaultScenario() throws Exception{
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+
+ processWizardPage.clickNext();
+ // Assert that user is able to go to next page
+ processWizardPage.isValidityStartDateDisplayed(true);
+ }
+
+ /**
+ * Populate fields with valid values (frequency, late arrival, availability flag, so on)
+ * Check that they are reflected on XML preview.
+ * @throws Exception
+ */
+ @Test
+ public void testTimingStepXmlPreview() throws Exception{
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+
+ // Get process from XML Preview
+ ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+
+ // Assert all the values entered on the Properties Page
+ LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
+ process.assertPropertiesInfo(processFromXML);
+ }
+
+ /**
+ * Add some properties to the feed (frequency, late parallel). Click edit XML.
+ * Remove both properties from XML. Check that properties were removed from matching fields.
+ * Now click Edit XML again. Add timezone and order properties to the XML.
+ * Check that Timezone and order were enabled and set to values what we've populated in XML.
+ * @throws Exception
+ */
+ @Test
+ public void testTimingStepEditXml() throws Exception{
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set Frequency and Parallel values on the Properties Page
+ processWizardPage.setFrequencyQuantity("10");
+ processWizardPage.setFrequencyUnit("minutes");
+ processWizardPage.setMaxParallelInstances(5);
+
+ // Get process from XML Preview
+ ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ processFromXML.setFrequency(null);
+ processFromXML.setParallel(1);
+
+ // Now click EditXML and set the updated XML here
+ processWizardPage.clickEditXml();
+ String xmlToString = processFromXML.toString();
+ processWizardPage.setProcessXml(xmlToString);
+ processWizardPage.clickEditXml();
+
+ // Assert Frequency and Parallel values
+ Assert.assertEquals(processWizardPage.getFrequencyQuantityText(), "",
+ "Frequency Quantity Should be empty on the Wizard window");
+ Assert.assertEquals(processWizardPage.getMaxParallelInstancesText(), "1",
+ "Unexpected Parallel on the Wizard window");
+
+ // Get process from XML Preview
+ processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+ // Set TimeZone and Order
+ TimeZone tz = TimeZone.getTimeZone("GMT-08:00");
+ processFromXML.setTimezone(tz);
+ processFromXML.setOrder(ExecutionType.LIFO);
+
+ // Now click EditXML and set the updated XML here
+ processWizardPage.clickEditXml();
+ xmlToString = processFromXML.toString();
+ processWizardPage.setProcessXml(xmlToString);
+ processWizardPage.clickEditXml();
+
+ // Assert TimeZone and Order
+ Assert.assertEquals(processWizardPage.getOrderText(), "LIFO",
+ "Unexpected Order on the Wizard window");
+ Assert.assertEquals(processWizardPage.getTimezoneText(), "GMT-08:00",
+ "Unexpected TimeZone on the Wizard window");
+ }
+
+ /**
+ * Check that timezone, frequency, parallel, order, retry policy,
+ * retry delay drop down lists contain correct items (time units etc.).
+ * @throws Exception
+ */
+ @Test
+ public void testTimingStepDropDownLists() throws Exception{
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Assert dropdown values
+ List<String> dropdownValues = processWizardPage.getTimezoneValues();
+ Assert.assertEquals(timeZones, dropdownValues, "TimeZone Values Are Not Equal");
+
+ dropdownValues = processWizardPage.getFrequencyUnitValues();
+ Assert.assertEquals(timeUnits, dropdownValues, "Frequency Unit Values Are Not Equal");
+
+ dropdownValues = processWizardPage.getMaxParallelInstancesValues();
+ Assert.assertEquals(parallel, dropdownValues, "Max Parallel Values Are Not Equal");
+
+ dropdownValues = processWizardPage.getOrderValues();
+ Assert.assertEquals(order, dropdownValues, "Order Unit Values Are Not Equal");
+
+ dropdownValues = processWizardPage.getRetryPolicyValues();
+ Assert.assertEquals(policy, dropdownValues, "Retry Policy Values Are Not Equal");
+
+ dropdownValues = processWizardPage.getRetryDelayUnitValues();
+ Assert.assertEquals(delayTimeUnits, dropdownValues, "Retry Delay Unit Values Are Not Equal");
+ }
+
+ /* Step 3 tests */
+
+ /**
+ * testClustersStepDefaultScenario
+ * Populate each field with correct values (name, validity ...). Check that
+ * user can go to the next step.
+ */
+ @Test
+ public void testClustersStepDefaultScenario()
+ throws URISyntaxException, IOException, AuthenticationException, InterruptedException, JAXBException {
+ bundles[0].submitClusters(cluster);
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+ processWizardPage.isAddInputButtonDisplayed(true);
+ }
+
+ /**
+ * Check that cluster drop down list contains correct list of items.
+ */
+ @Test
+ public void testClustersStepDropDownList()
+ throws URISyntaxException, IOException, AuthenticationException, InterruptedException, JAXBException {
+ //submit all clusters
+ List<String> clusters = new ArrayList<>();
+ ClusterMerlin clusterMerlin = bundles[0].getClusterElement();
+ String clusterName = clusterMerlin.getName();
+ for(int i = 1; i < 6; i++) {
+ clusterMerlin.setName(clusterName + i);
+ AssertUtil.assertSucceeded(cluster.getClusterHelper().submitEntity(clusterMerlin.toString()));
+ clusters.add(clusterMerlin.getName());
+ }
+ //go to clusters page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+ List<String> dropdownValues = new ArrayList<>(processWizardPage.getClustersFromDropDown());
+
+ //clean all clusters which belong to anything else then current test class
+ String testClassName = ProcessSetupTest.class.getSimpleName();
+ for(int i = 0; i < dropdownValues.size(); i++) {
+ if (!dropdownValues.get(i).contains(testClassName)) {
+ dropdownValues.remove(i);
+ }
+ }
+ Collections.sort(clusters);
+ Collections.sort(dropdownValues);
+ Assert.assertEquals(clusters, dropdownValues, "Clusters Drop Down Values Are Not Equal");
+ }
+
+ /**
+ * Click on validity start/end, check that pop up calendars have been shown.
+ */
+ @Test
+ public void testClustersStepPopupCalendars() {
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ //click on respective fields
+ processWizardPage.clickOnValidityStart();
+ processWizardPage.clickOnValidityEnd();
+ }
+
+ /**
+ * Click on add cluster. Check that new cluster block appears. Populate it with values
+ * and check that XML preview shows both clusters. Remove the cluster and check that XML
+ * has the only cluster.
+ */
+ @Test
+ public void testClustersStepAddDeleteCluster() throws Exception {
+ bundles[0].submitClusters(cluster);
+ //submit one extra cluster
+ ClusterMerlin clusterMerlin = bundles[0].getClusterElement();
+ clusterMerlin.setName(clusterMerlin.getName() + 1);
+ AssertUtil.assertSucceeded(cluster.getClusterHelper().submitEntity(clusterMerlin.toString()));
+
+ Cluster processCluster = new Cluster();
+ processCluster.setName(clusterMerlin.getName());
+ processCluster.setValidity(process.getClusters().getClusters().get(0).getValidity());
+ process.addProcessCluster(processCluster);
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Add clusters
+ processWizardPage.setClusters(process.getClusters());
+ ProcessMerlin xmlPreview = processWizardPage.getProcessMerlinFromProcessXml();
+
+ //compare clusters
+ LOGGER.info(String.format("Comparing clusters of process: %n%s%n and preview: %n%s%n.", process, xmlPreview));
+ ProcessMerlin.assertClustersEqual(process.getClusters().getClusters(), xmlPreview.getClusters().getClusters());
+
+ //delete one cluster and repeat the check
+ processWizardPage.deleteLastCluster();
+ xmlPreview = processWizardPage.getProcessMerlinFromProcessXml();
+ process.getClusters().getClusters().remove(1);
+
+ //compare clusters
+ LOGGER.info(String.format("Comparing clusters of process: %n%s%n and preview: %n%s%n.", process, xmlPreview));
+ ProcessMerlin.assertClustersEqual(process.getClusters().getClusters(), xmlPreview.getClusters().getClusters());
+ }
+
+ /**
+ * Populate all fields with valid values and check that they are reflected on XML
+ * preview. Click edit XML. Change validity and cluster name. Check that changes
+ * are reflected on XML as well as on wizard page. Edit xml again. Add new cluster
+ * and check that new cluster block has been added on wizard page.
+ */
+ @Test
+ public void testClusterStepEditXml() throws Exception {
+ bundles[0].submitClusters(cluster);
+ ClusterMerlin clusterMerlin = bundles[0].getClusterElement();
+ String firstClusterName = clusterMerlin.getName();
+ clusterMerlin.setName(firstClusterName + 2);
+ AssertUtil.assertSucceeded(cluster.getClusterHelper().submitEntity(clusterMerlin.toString()));
+
+ //set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ //set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ //set cluster
+ processWizardPage.setClusters(process.getClusters());
+
+ //compare preview and source data
+ ProcessMerlin xmlPreview = processWizardPage.getProcessMerlinFromProcessXml();
+ LOGGER.info(String.format("Comparing clusters of process: %n%s%n and preview: %n%s%n.", process, xmlPreview));
+ ProcessMerlin.assertClustersEqual(process.getClusters().getClusters(), xmlPreview.getClusters().getClusters());
+
+ //change validity and name and push it to xmlPreview
+ Date date = new Date();
+ xmlPreview.getClusters().getClusters().get(0).getValidity().setEnd(date);
+ xmlPreview.getClusters().getClusters().get(0).setName(clusterMerlin.getName());
+ processWizardPage.clickEditXml();
+ processWizardPage.setProcessXml(xmlPreview.toString());
+ processWizardPage.clickEditXml();
+
+ //check that validity end is changed on wizard
+ String endUI = processWizardPage.getValidityEnd();
+ SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm");
+ format.setTimeZone(TimeZone.getTimeZone("UTC"));
+ String endSource = format.format(date);
+ Assert.assertEquals(endUI, endSource, "Validity end should be updated on wizard.");
+ Assert.assertEquals(processWizardPage.getClusterName(0), clusterMerlin.getName(),
+ "Cluster name should be updated on wizard.");
+
+ //add cluster to process preview
+ int initCount = processWizardPage.getWizardClusterCount();
+ Cluster processCluster = new Cluster();
+ process = new ProcessMerlin(xmlPreview);
+ processCluster.setName(firstClusterName);
+ processCluster.setValidity(xmlPreview.getClusters().getClusters().get(0).getValidity());
+ process.addProcessCluster(processCluster);
+ processWizardPage.clickEditXml();
+ processWizardPage.setProcessXml(xmlPreview.toString());
+ processWizardPage.clickEditXml();
+
+ //check that changes are reflected on wizard
+ int finalCount = processWizardPage.getWizardClusterCount();
+ Assert.assertEquals(finalCount - initCount, 1, "Cluster should have been added to wizard.");
+ Assert.assertEquals(processWizardPage.getClusterName(1), firstClusterName,
+ "Cluster name should be updated on wizard.");
+ }
+
+ /* Step 4 tests */
+
+ /**
+ * Add input and output. Populate each field with correct values(name, feed, instance ...).
+ * Check that user can go to the next step.
+ * @throws Exception
+ */
+ @Test
+ public void testInOutStepDefaultScenario() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Input Output Page
+ processWizardPage.setInputOutputInfo(process);
+ processWizardPage.clickNext();
+
+ // Assert that user is able to go on the next page
+ processWizardPage.isSaveButtonDisplayed(true);
+
+
+ }
+
+ /**
+ * Check that user is allowed to go to the next page without adding inputs/outputs.
+ * @throws Exception
+ */
+ @Test
+ public void testInOutStepWithoutInOuts() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Do not set values on the Input Output Page
+ processWizardPage.clickNext();
+
+ // Assert that user is able to go on the next page
+ processWizardPage.isSaveButtonDisplayed(true);
+
+ }
+
+ /**
+ * Add input. Set instance with start time after end.
+ * Check that user is not allowed to go to the next step and has been notified with an alert.
+ * Check the same for invalid EL expression.
+ * @throws Exception
+ */
+ @Test
+ public void testInOutInvalidInstance() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set start date after end date in Input
+ process.getInputs().getInputs().get(0).setStart("now(0, 0)");
+ process.getInputs().getInputs().get(0).setEnd("now(0, -5)");
+
+ // Set Input Values on the Input Output Page
+ processWizardPage.setInputInfo(process.getInputs());
+ processWizardPage.clickNext();
+
+ // Assert User should not be allowed to go on the next page
+ processWizardPage.isSaveButtonDisplayed(false);
+
+ // Delete the current Input
+ processWizardPage.clickDeleteInput();
+
+ // Set invalid EL expression
+ process.getInputs().getInputs().get(0).setStart("bad(0, 0)");
+ process.getInputs().getInputs().get(0).setEnd("bad(0, 0)");
+
+ // Set new Input Values on the Input Output Page
+ processWizardPage.setInputInfo(process.getInputs());
+ processWizardPage.clickNext();
+
+ // Assert User should not be allowed to go on the next page
+ processWizardPage.isSaveButtonDisplayed(false);
+ }
+
+ /**
+ * Check that input/output feed drop down list contains correct list of feeds.
+ * @throws Exception
+ */
+ @Test
+ public void testInOutStepDropDownFeeds() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Click Add Input and Output Buttons
+ processWizardPage.clickAddInput();
+ processWizardPage.clickAddOutput();
+
+ List<String> expectedDropdownValues = new ArrayList<>();
+ expectedDropdownValues.add("-Select feed-");
+ expectedDropdownValues.add(process.getInputs().getInputs().get(0).getFeed());
+ expectedDropdownValues.add(process.getOutputs().getOutputs().get(0).getFeed());
+ Collections.sort(expectedDropdownValues);
+
+ // Assert Input and Output Feed Dropdown values
+ List<String> actualDropdownValues = processWizardPage.getInputValues(0);
+ Collections.sort(actualDropdownValues);
+ Assert.assertEquals(expectedDropdownValues, actualDropdownValues,
+ "Input Feed Dropdown Values Are Not Equal");
+
+ actualDropdownValues = processWizardPage.getOutputValues(0);
+ Assert.assertEquals(expectedDropdownValues, actualDropdownValues,
+ "Output Feed Dropdown Values Are Not Equal");
+ }
+
+ /**
+ * Add input. Check that it has been added to wizard as well as to XML preview.
+ * Click edit xml. Change input name and add output in xml.
+ * Check that output has been added on wizard page and input name has been changed as well.
+ * @throws Exception
+ */
+ @Test
+ public void testInOutStepPreviewEditXml() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set Input Values on the Input Output Page
+ processWizardPage.setInputInfo(process.getInputs());
+
+ // Assert Input values on Wizard
+ Assert.assertEquals(processWizardPage.getInputNameText(0), process.getInputs().getInputs().get(0).getName(),
+ "Unexpected Input Name on the Wizard window");
+ Assert.assertEquals(processWizardPage.getInputFeedText(0), process.getInputs().getInputs().get(0).getFeed(),
+ "Unexpected Input Feed on the Wizard window");
+ Assert.assertEquals(processWizardPage.getInputStartText(0), process.getInputs().getInputs().get(0).getStart(),
+ "Unexpected Input Start on the Wizard window");
+ Assert.assertEquals(processWizardPage.getInputEndText(0), process.getInputs().getInputs().get(0).getEnd(),
+ "Unexpected Input End on the Wizard window");
+
+ // Get process from XML Preview
+ ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+
+ // Assert Input values on the XML Preview
+ LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
+ process.assertInputValues(processFromXML);
+
+ // Change Input Name and Set Output in the XML
+ processFromXML.getInputs().getInputs().get(0).setName("newInputData");
+ processFromXML.setOutputs(process.getOutputs());
+
+ // Now click EditXML and set the updated XML here
+ processWizardPage.clickEditXml();
+ String xmlToString = processFromXML.toString();
+ processWizardPage.setProcessXml(xmlToString);
+ processWizardPage.clickEditXml();
+
+ // Assert Input Name and Output values on Wizard
+ Assert.assertEquals(processWizardPage.getInputNameText(0), "newInputData",
+ "Unexpected Input Name on the Wizard window");
+ Assert.assertEquals(processWizardPage.getOutputNameText(0),
+ process.getOutputs().getOutputs().get(0).getName(),
+ "Unexpected Output Name on the Wizard window");
+ Assert.assertEquals(processWizardPage.getOutputFeedText(0),
+ process.getOutputs().getOutputs().get(0).getFeed(),
+ "Unexpected Output Feed on the Wizard window");
+ Assert.assertEquals(processWizardPage.getOutputInstanceText(0),
+ process.getOutputs().getOutputs().get(0).getInstance(),
+ "Unexpected Output Instance on the Wizard window");
+ }
+
+ /**
+ * Add input. Check that it has been added to wizard as well to XML.
+ * Delete it. Check that it has been removed from wizard as well as from XML.
+ * Repeat the same for the output.
+ * @throws Exception
+ */
+ @Test
+ public void testInOutStepAddDeleteInOut() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set Input Values on the Input Output Page
+ processWizardPage.setInputInfo(process.getInputs());
+
+ // Assert Input values on Wizard
+ Assert.assertEquals(processWizardPage.getInputNameText(0), process.getInputs().getInputs().get(0).getName(),
+ "Unexpected Input Name on the Wizard window");
+ Assert.assertEquals(processWizardPage.getInputFeedText(0), process.getInputs().getInputs().get(0).getFeed(),
+ "Unexpected Input Feed on the Wizard window");
+ Assert.assertEquals(processWizardPage.getInputStartText(0), process.getInputs().getInputs().get(0).getStart(),
+ "Unexpected Input Start on the Wizard window");
+ Assert.assertEquals(processWizardPage.getInputEndText(0), process.getInputs().getInputs().get(0).getEnd(),
+ "Unexpected Input End on the Wizard window");
+
+ // Get process from XML Preview
+ ProcessMerlin processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+
+ // Assert Input values on the XML Preview
+ LOGGER.info(String.format("Comparing source process: %n%s%n and preview: %n%s%n.", process, processFromXML));
+ process.assertInputValues(processFromXML);
+
+ // Delete the input
+ processWizardPage.clickDeleteInput();
+
+ // Assert on the click of delete Input the Input is deleted
+ processWizardPage.isInputNameDisplayed(0, false);
+
+ // Set Output Values on the Input Output Page
+ processWizardPage.setOutputInfo(process.getOutputs());
+
+ // Assert Output values on Wizard
+ Assert.assertEquals(processWizardPage.getOutputNameText(0),
+ process.getOutputs().getOutputs().get(0).getName(),
+ "Unexpected Output Name on the Wizard window");
+ Assert.assertEquals(processWizardPage.getOutputFeedText(0),
+ process.getOutputs().getOutputs().get(0).getFeed(),
+ "Unexpected Output Feed on the Wizard window");
+ Assert.assertEquals(processWizardPage.getOutputInstanceText(0),
+ process.getOutputs().getOutputs().get(0).getInstance(),
+ "Unexpected Output Instance on the Wizard window");
+
+ // Get process from XML Preview
+ processFromXML = processWizardPage.getProcessMerlinFromProcessXml();
+
+ // Assert Output values on the XML Preview
+ LOGGER.info(String.format("Comparing source process : %n%s%n and preview: %n%s%n.", process, processFromXML));
+ process.assertOutputValues(processFromXML);
+
+ // Delete the output
+ processWizardPage.clickDeleteOutput();
+
+ // Assert on the click of delete Input the Input is deleted
+ processWizardPage.isOutputNameDisplayed(0, false);
+ }
+
+ /* Step 5 tests */
+
+ /**
+ * Create process. Using API check that process was created.
+ * @throws Exception
+ */
+ @Test
+ public void testSummaryStepDefaultScenario() throws Exception{
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Input Output Page
+ processWizardPage.setInputOutputInfo(process);
+ processWizardPage.clickNext();
+
+ // Save the Process
+ processWizardPage.clickSave();
+
+ // Assert the response using API to validate if the feed creation went successfully
+ ServiceResponse response = prism.getProcessHelper().getEntityDefinition(process.toString());
+ AssertUtil.assertSucceeded(response);
}
+ /**
+ * Go through all properties which are shown on page. Check that they are equal to
+ * those which were populated in previous steps.
+ */
+ @Test
+ public void testSummaryStepAllProperties()
+ throws URISyntaxException, IOException, AuthenticationException, InterruptedException, JAXBException {
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ process.setTags("first=yes,second=yes,third=no");
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Input Output Page
+ processWizardPage.setInputOutputInfo(process);
+ processWizardPage.clickNext();
+
+ //get process from summary and compare it with the source
+ ProcessMerlin summaryProcess = ProcessMerlin.getEmptyProcess(process);
+ summaryProcess = processWizardPage.getProcessFromSummaryBox(summaryProcess);
+ summaryProcess.assertEquals(process);
+ }
+
+ /**
+ * Check that all properties which are shown on page are equal to those which are
+ * shown on XML Preview. Click Edit XML. Add new input. Check that it has been
+ * added on wizard.
+ */
+ @Test
+ public void testSummaryStepEditXml() throws Exception {
+
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ process.setTags("first=yes,second=yes,third=no");
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Input Output Page
+ processWizardPage.setInputOutputInfo(process);
+ processWizardPage.clickNext();
+
+ //get process from summary and from xml and compare them
+ ProcessMerlin summaryProcess = ProcessMerlin.getEmptyProcess(process);
+ summaryProcess = processWizardPage.getProcessFromSummaryBox(summaryProcess);
+ ProcessMerlin previewProcess = processWizardPage.getProcessMerlinFromProcessXml();
+ summaryProcess.assertEquals(previewProcess);
+
+ //add input to preview cluster
+ Input oldInput = previewProcess.getInputs().getInputs().get(0);
+ Input newInput = new Input();
+ newInput.setFeed(oldInput.getFeed());
+ newInput.setName("newInput");
+ newInput.setStart("now(-40, 0)");
+ newInput.setEnd("now(20, 0)");
+ previewProcess.getInputs().getInputs().add(newInput);
+
+ //push new process to xml preview
+ processWizardPage.clickEditXml();
+ processWizardPage.setProcessXml(previewProcess.toString());
+ processWizardPage.clickEditXml();
+
+ //get process from summary and check that new input is available
+ summaryProcess = processWizardPage.getProcessFromSummaryBox(ProcessMerlin.getEmptyProcess(summaryProcess));
+ LOGGER.info(String.format("Comparing summary : %n%s%n and preview: %n%s%n.", summaryProcess, previewProcess));
+ summaryProcess.assertInputValues(previewProcess);
+ }
+
+ /**
+ * Click on EditXML. Break xml. Check that entity is
+ * not accepted and preview xml is being reverted to previous state.
+ */
+ @Test
+ public void testSummaryStepEditXmlInvalidChanges()
+ throws Exception {
+ bundles[0].submitClusters(cluster);
+ bundles[0].submitFeeds(prism);
+
+ bundles[0].getInputFeedNameFromBundle();
+
+ process.setTags("first=yes,second=yes,third=no");
+ // Set values on the General Info Page
+ processWizardPage.setProcessGeneralInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Properties Page
+ processWizardPage.setProcessPropertiesInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Cluster Info Page
+ processWizardPage.setProcessClustersInfo(process);
+ processWizardPage.clickNext();
+
+ // Set values on the Input Output Page
+ processWizardPage.setInputOutputInfo(process);
+ processWizardPage.clickNext();
+
+ //get process from xml preview
+ ProcessMerlin previewProcess1 = processWizardPage.getProcessMerlinFromProcessXml();
+ String processString = previewProcess1.toString();
+
+ //damage the xml and populate it back to preview
+ processString = processString.substring(0, processString.length() - 3);
+ processWizardPage.clickEditXml();
+ processWizardPage.setProcessXml(processString);
+ processWizardPage.clickEditXml();
+
+ //get xml preview and compare with initial state
+ ProcessMerlin previewProcess2 = processWizardPage.getProcessMerlinFromProcessXml();
+ previewProcess2.assertEquals(previewProcess1);
+ }
}
[2/2] falcon git commit: FALCON-1249 Tests for process setup wizard
conributed by Namit Maheshwari and Paul Isaychuk
Posted by ra...@apache.org.
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 <ra...@apache.org>
Authored: Thu Jun 4 11:51:00 2015 -0700
Committer: Raghav Kumar Gautam <ra...@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;
}
}