Repository: falcon Updated Branches: refs/heads/master 3f23d783e -> eecf7f533
FALCON-1210: Process Setup tests for testing header and general step default scenario contributed by Raghav Kumar Gautam Project: http://git-wip-us.apache.org/repos/asf/falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/eecf7f53 Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/eecf7f53 Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/eecf7f53 Branch: refs/heads/master Commit: eecf7f533f32ca9274666a9a545934dcc7bdb21b Parents: 3f23d78 Author: Raghav Kumar Gautam <[email protected]> Authored: Wed May 13 18:08:49 2015 -0700 Committer: Raghav Kumar Gautam <[email protected]> Committed: Wed May 13 18:08:59 2015 -0700 ---------------------------------------------------------------------- falcon-regression/CHANGES.txt | 2 + .../ui/search/AbstractSearchPage.java | 1 + .../regression/ui/search/NewProcessPage.java | 44 ---- .../falcon/regression/ui/search/PageHeader.java | 4 +- .../regression/ui/search/ProcessWizardPage.java | 223 +++++++++++++++++++ .../regression/searchUI/ProcessSetupTest.java | 111 +++++++++ 6 files changed, 339 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/falcon/blob/eecf7f53/falcon-regression/CHANGES.txt ---------------------------------------------------------------------- diff --git a/falcon-regression/CHANGES.txt b/falcon-regression/CHANGES.txt index 2e9297a..00e4840 100644 --- a/falcon-regression/CHANGES.txt +++ b/falcon-regression/CHANGES.txt @@ -5,6 +5,8 @@ Trunk (Unreleased) INCOMPATIBLE CHANGES NEW FEATURES + FALCON-1210 Process Setup tests for testing header and general step default scenario (Raghav Kumar Gautam) + FALCON-1201 Feed Setup tests for testing header and default scenario (Namit Maheshwari) FALCON-1198 Test buttons available on search results page (Ruslan Ostafiychuk) http://git-wip-us.apache.org/repos/asf/falcon/blob/eecf7f53/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 161d545..e72ce67 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 @@ -30,6 +30,7 @@ import org.openqa.selenium.support.PageFactory; public abstract class AbstractSearchPage extends Page { public static final String UI_URL = MerlinConstants.PRISM_URL; + public static final long PAGELOAD_TIMEOUT_THRESHOLD = 10; public AbstractSearchPage(WebDriver driver) { super(driver); http://git-wip-us.apache.org/repos/asf/falcon/blob/eecf7f53/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewProcessPage.java ---------------------------------------------------------------------- diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewProcessPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewProcessPage.java deleted file mode 100644 index f7d5bad..0000000 --- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewProcessPage.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.falcon.regression.ui.search; - -import org.apache.falcon.regression.core.util.UIAssert; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.FindBys; - -/** Page object of the Process creation page. */ -public class NewProcessPage extends AbstractSearchPage { - - @FindBys({ - @FindBy(className = "mainUIView"), - @FindBy(className = "entityForm") - }) - private WebElement processBox; - - public NewProcessPage(WebDriver driver) { - super(driver); - } - - @Override - public void checkPage() { - UIAssert.assertDisplayed(processBox, "Process box"); - } -} http://git-wip-us.apache.org/repos/asf/falcon/blob/eecf7f53/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java ---------------------------------------------------------------------- diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java index 0a41a5e..c166eaf 100644 --- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java +++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java @@ -184,12 +184,12 @@ public class PageHeader { return feedPage; } - public NewProcessPage doCreateProcess() { + public ProcessWizardPage doCreateProcess() { UIAssert.assertDisplayed(processCreateButton, "Process create button"); Assert.assertEquals(processCreateButton.getText(), "Process", "Unexpected text on create process button"); processCreateButton.click(); - final NewProcessPage processPage = PageFactory.initElements(driver, NewProcessPage.class); + final ProcessWizardPage processPage = PageFactory.initElements(driver, ProcessWizardPage.class); processPage.checkPage(); return processPage; } http://git-wip-us.apache.org/repos/asf/falcon/blob/eecf7f53/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 new file mode 100644 index 0000000..e429a60 --- /dev/null +++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/ProcessWizardPage.java @@ -0,0 +1,223 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.falcon.regression.ui.search; + +import com.google.common.collect.Lists; +import org.apache.commons.lang.StringUtils; +import org.apache.falcon.entity.v0.process.ACL; +import org.apache.falcon.entity.v0.process.Workflow; +import org.apache.falcon.regression.Entities.ProcessMerlin; +import org.apache.falcon.regression.core.util.UIAssert; +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.util.List; +import java.util.TimeZone; + +/** Page object of the Process creation page. */ +public class ProcessWizardPage extends AbstractSearchPage { + + @FindBys({ + @FindBy(className = "mainUIView"), + @FindBy(className = "entityForm") + }) + private WebElement processBox; + + public ProcessWizardPage(WebDriver driver) { + super(driver); + } + + @Override + public void checkPage() { + UIAssert.assertDisplayed(processBox, "Process box"); + } + + private WebElement getNextButton() { + return driver.findElement(By.id("nextButton")); + } + + public void pressNext() { + getNextButton().click(); + } + + /*----- Step1 elements & operations ----*/ + private WebElement getName() { + return driver.findElement(By.id("entityNameField")); + } + + public void setName(String name) { + final WebElement nameElement = getName(); + nameElement.clear(); + for (String s : name.split("")) { + nameElement.sendKeys(s); + } + } + private WebElement getTagsSection() { + return driver.findElement(By.id("tagsSection")); + } + + private WebElement getAddTagButton() { + return driver.findElement(By.className("formViewContainer")) + .findElement(By.xpath("./form/div[4]/button")); + } + + private List<WebElement> getDeleteTagButtons() { + return getTagsSection().findElements(By.tagName("button")); + } + + private List<WebElement> getTagTextFields() { + return getTagsSection().findElements(By.tagName("input")); + } + + public void deleteTags() { + //delete all tags + final List<WebElement> deleteTagButtons = getDeleteTagButtons(); + for (WebElement deleteTagButton : Lists.reverse(deleteTagButtons)) { + deleteTagButton.click(); + } + for (WebElement textField : getTagTextFields()) { + textField.clear(); + } + } + + 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(); + } + 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); + } + } + + private WebElement getWfName() { + return driver.findElement(By.id("workflowNameField")); + } + + private WebElement getOozieRadio() { + return driver.findElement(By.id("oozieEngineRadio")); + } + + private WebElement getPigRadio() { + return driver.findElement(By.id("pigEngineRadio")); + } + + private WebElement getHiveRadio() { + return driver.findElement(By.id("hiveEngineRadio")); + } + + private Select getEngineVersion() { + return new Select(driver.findElement(By.id("engineVersionField"))); + } + + private WebElement getPath() { + return driver.findElement(By.id("pathField")); + } + + public void setWorkflow(Workflow processWf) { + final WebElement wfName = getWfName(); + wfName.clear(); + wfName.sendKeys(processWf.getName()); + switch (processWf.getEngine()) { + case OOZIE: + getOozieRadio().click(); + break; + case PIG: + getPigRadio().click(); + break; + case HIVE: + getHiveRadio().click(); + break; + default: + Assert.fail("Unexpected workflow engine: " + processWf.getEngine()); + } + final String version = processWf.getVersion(); + if (StringUtils.isNotEmpty(version) && !version.equals("1.0")) { + getEngineVersion().selectByVisibleText(version); + } + final WebElement path = getPath(); + path.clear(); + path.sendKeys(processWf.getPath()); + } + + private WebElement getAclOwner() { + return driver.findElement(By.name("aclOwnerInput")); + } + + private WebElement getAclGroup() { + return driver.findElement(By.name("aclGroupInput")); + } + + private WebElement getAclPerm() { + return driver.findElement(By.name("aclPermissionsInput")); + } + + public void setAcl(ACL acl) { + final WebElement aclOwner = getAclOwner(); + aclOwner.clear(); + aclOwner.sendKeys(acl.getOwner()); + final WebElement aclGroup = getAclGroup(); + aclGroup.clear(); + aclGroup.sendKeys(acl.getGroup()); + final WebElement aclPerm = getAclPerm(); + aclPerm.clear(); + aclPerm.sendKeys(acl.getPermission()); + } + + public void doStep1(ProcessMerlin process) { + setName(process.getName()); + final String tags = StringUtils.trimToEmpty(process.getTags()); + setTags(Arrays.asList(tags.split(","))); + 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 ----*/ + private Select getTimezone() { + return new Select(driver.findElement(By.id("timeZoneSelect"))); + } + + public void setTimezone(TimeZone timezone) { + getTimezone().selectByValue(timezone.getDisplayName()); + } +} http://git-wip-us.apache.org/repos/asf/falcon/blob/eecf7f53/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 new file mode 100644 index 0000000..4e1474c --- /dev/null +++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/ProcessSetupTest.java @@ -0,0 +1,111 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.falcon.regression.searchUI; + +import org.apache.commons.lang.StringUtils; +import org.apache.falcon.entity.v0.Frequency; +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.util.BundleUtil; +import org.apache.falcon.regression.core.util.HadoopUtil; +import org.apache.falcon.regression.core.util.OSUtil; +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.log4j.Logger; +import org.apache.oozie.client.OozieClient; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** 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; + + @BeforeMethod(alwaysRun = true) + public void setup() throws IOException { + cleanAndGetTestDir(); + HadoopUtil.uploadDir(serverFS.get(0), aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE); + bundles[0] = BundleUtil.readELBundle(); + bundles[0] = new Bundle(bundles[0], servers.get(0)); + bundles[0].generateUniqueBundle(this); + bundles[0].setInputFeedDataPath(feedInputPath); + bundles[0].setProcessWorkflow(aggregateWorkflowDir); + bundles[0].setProcessValidity("2010-01-02T01:00Z", "2010-01-02T01:11Z"); + bundles[0].setProcessInputStartEnd("now(0, 0)", "now(0, 0)"); + bundles[0].setProcessPeriodicity(5, Frequency.TimeUnit.minutes); + bundles[0].setOutputFeedPeriodicity(5, Frequency.TimeUnit.minutes); + bundles[0].setOutputFeedLocationData(feedOutputPath); + + openBrowser(); + final LoginPage loginPage = LoginPage.open(getDriver()); + SearchPage searchPage = loginPage.doDefaultLogin(); + processWizardPage = searchPage.getPageHeader().doCreateProcess(); + processWizardPage.checkPage(); + } + + @AfterMethod(alwaysRun = true) + public void tearDown() throws IOException { + removeTestClassEntities(); + closeBrowser(); + } + + /** + * Test header of the EntityPage. + * Check that buttons (logout, entities, uploadXml, help, Falcon) are present, and names are + * correct. + * Check the user name on header. + * "Create an entity"/"upload an entity" headers. + * Check that each button navigates user to correct page. + * @throws Exception + */ + @Test + public void testHeader() throws Exception { + processWizardPage.getPageHeader().checkHeader(); + } + + /** + * Populate fields with valid values (name, tag, workflow, engine, version, wf path) + * and check that user can go to the next step. + */ + @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); + } + +}
