You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by ro...@apache.org on 2015/04/22 14:52:52 UTC

falcon git commit: FALCON-1167 Homepage & Login test for search-ui. Contributed by Raghav Kumar Gautam

Repository: falcon
Updated Branches:
  refs/heads/master 3db317f8a -> 136506482


FALCON-1167 Homepage & Login test for search-ui. 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/13650648
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/13650648
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/13650648

Branch: refs/heads/master
Commit: 1365064828439468996f5a523ecf59d0c2dd8754
Parents: 3db317f
Author: Ruslan Ostafiychuk <ro...@apache.org>
Authored: Wed Apr 22 15:50:07 2015 +0300
Committer: Ruslan Ostafiychuk <ro...@apache.org>
Committed: Wed Apr 22 15:50:07 2015 +0300

----------------------------------------------------------------------
 falcon-regression/CHANGES.txt                   |   2 +
 falcon-regression/merlin-core/pom.xml           |  11 +
 .../core/enumsAndConstants/MerlinConstants.java |   5 +
 .../falcon/regression/core/util/AssertUtil.java |  25 +-
 .../falcon/regression/core/util/UIAssert.java   |  52 +++++
 falcon-regression/merlin/pom.xml                |   8 -
 .../apache/falcon/regression/ui/pages/Page.java |   3 +
 .../ui/search/AbstractSearchPage.java           |  56 +++++
 .../falcon/regression/ui/search/LoginPage.java  | 117 ++++++++++
 .../regression/ui/search/NewClusterPage.java    |  44 ++++
 .../regression/ui/search/NewFeedPage.java       |  44 ++++
 .../regression/ui/search/NewMirrorPage.java     |  44 ++++
 .../regression/ui/search/NewProcessPage.java    |  44 ++++
 .../falcon/regression/ui/search/PageHeader.java | 231 ++++++++++++++++++
 .../falcon/regression/ui/search/SearchPage.java | 234 +++++++++++++++++++
 .../regression/searchUI/HomePageTest.java       |  84 +++++++
 .../falcon/regression/searchUI/LoginTest.java   | 112 +++++++++
 falcon-regression/pom.xml                       |  13 +-
 18 files changed, 1115 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/CHANGES.txt
----------------------------------------------------------------------
diff --git a/falcon-regression/CHANGES.txt b/falcon-regression/CHANGES.txt
index 8ed2af9..7b56be8 100644
--- a/falcon-regression/CHANGES.txt
+++ b/falcon-regression/CHANGES.txt
@@ -6,6 +6,8 @@ Trunk (Unreleased)
 
   NEW FEATURES
 
+   FALCON-1167 Homepage & Login test for search-ui (Raghav Kumar Gautam via Ruslan Ostafiychuk)
+
    FALCON-1067 Add test in falcon-regression for feed instance listing api(Karishma G 
    via Samarth G) 
  

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin-core/pom.xml
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/pom.xml b/falcon-regression/merlin-core/pom.xml
index a83696d..e0180b4 100644
--- a/falcon-regression/merlin-core/pom.xml
+++ b/falcon-regression/merlin-core/pom.xml
@@ -164,5 +164,16 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-exec</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-firefox-driver</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-support</artifactId>
+        </dependency>
+
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/enumsAndConstants/MerlinConstants.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/enumsAndConstants/MerlinConstants.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/enumsAndConstants/MerlinConstants.java
index 7654c52..b8eafe4 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/enumsAndConstants/MerlinConstants.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/enumsAndConstants/MerlinConstants.java
@@ -35,6 +35,11 @@ public final class MerlinConstants {
 
     private static final Logger LOGGER = Logger.getLogger(MerlinConstants.class);
 
+    public static final String PRISM_URL = Config.getProperty("prism.hostname");
+
+    public static final String HELP_URL =
+        Config.getProperty("falcon.help.url", "http://falcon.apache.org/");
+
     public static final boolean IS_SECURE =
         "kerberos".equals(new Configuration().get("hadoop.security.authentication", "simple"));
 

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/AssertUtil.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/AssertUtil.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/AssertUtil.java
index 80f2b0f..3abca7a 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/AssertUtil.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/AssertUtil.java
@@ -18,6 +18,7 @@
 
 package org.apache.falcon.regression.core.util;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.falcon.entity.v0.EntityType;
 import org.apache.falcon.regression.core.bundle.Bundle;
@@ -36,6 +37,7 @@ import org.testng.Assert;
 
 import javax.xml.bind.JAXBException;
 import java.io.IOException;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -216,7 +218,7 @@ public final class AssertUtil {
         Assert.assertFalse(execResult.hasSuceeded(),
                 "Unexpectedly succeeded execResult: " + execResult);
         Assert.assertTrue(execResult.getError().contains(expectedMessage),
-                "Expected error: " + expectedMessage +  " in execResult: " + execResult);
+            "Expected error: " + expectedMessage + " in execResult: " + execResult);
     }
 
     /**
@@ -255,7 +257,8 @@ public final class AssertUtil {
      * @throws JAXBException
      */
     public static void assertFailed(ServiceResponse response) throws JAXBException {
-        Assert.assertNotEquals(response.getMessage(), "null", "response message should not be null");
+        Assert.assertNotEquals(response.getMessage(), "null",
+            "response message should not be null");
 
         Assert.assertEquals(Util.parseResponse(response).getStatus(), APIResult.Status.FAILED);
         Assert.assertEquals(response.getCode(), 400);
@@ -388,4 +391,22 @@ public final class AssertUtil {
         LOGGER.info("Got exception: " + ExceptionUtils.getStackTrace(e));
         Assert.fail("Failing because of exception.");
     }
+
+    public static void assertEmpty(String str, String message) {
+        if (StringUtils.isNotEmpty(str)) {
+            Assert.fail(String.format("%s expected [empty string/null] found [%s]", message, str));
+        }
+    }
+
+    public static <E> void assertEmpty(Collection<E> collection, String message) {
+        if (!collection.isEmpty()) {
+            Assert.fail(
+                String.format("%s expected [empty collection] found [%s]", message, collection));
+        }
+    }
+    public static void assertNotEmpty(String str, String message) {
+        if (StringUtils.isEmpty(str)) {
+            Assert.fail(String.format("%s expected non-empty string found [%s]", message, str));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/UIAssert.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/UIAssert.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/UIAssert.java
new file mode 100644
index 0000000..f4befd4
--- /dev/null
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/UIAssert.java
@@ -0,0 +1,52 @@
+/**
+ * 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.core.util;
+
+import org.apache.log4j.Logger;
+import org.openqa.selenium.WebElement;
+import org.testng.Assert;
+
+/**
+ * Assertion related to UI testing.
+ */
+public final class UIAssert {
+    private UIAssert() {
+        throw new AssertionError("Instantiating utility class...");
+    }
+    private static final Logger LOGGER = Logger.getLogger(UIAssert.class);
+
+
+    public static void assertDisplayed(WebElement element, String webElementName) {
+        LOGGER.info(String.format("Checking if WebElement '%s' is displayed", webElementName));
+        int timeoutSeconds = 2;
+        for (int i = 0; !element.isDisplayed() && i < timeoutSeconds * 10; i++) {
+            TimeUtil.sleepSeconds(0.1);
+        }
+        Assert.assertTrue(element.isDisplayed(),
+            String.format("WebElement '%s' should have been displayed", webElementName));
+        LOGGER.info(String.format("WebElement '%s' is displayed", webElementName));
+    }
+
+    public static void assertNotDisplayed(WebElement clusterForm, String webElementName) {
+        LOGGER.info(String.format("Checking if WebElement '%s' is displayed", webElementName));
+        Assert.assertFalse(clusterForm.isDisplayed(),
+            String.format("WebElement '%s' should NOT have been displayed", webElementName));
+        LOGGER.info(String.format("WebElement '%s' is not displayed", webElementName));
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/pom.xml
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/pom.xml b/falcon-regression/merlin/pom.xml
index 7d096b1..14b43ec 100644
--- a/falcon-regression/merlin/pom.xml
+++ b/falcon-regression/merlin/pom.xml
@@ -69,13 +69,5 @@
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.seleniumhq.selenium</groupId>
-            <artifactId>selenium-firefox-driver</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.seleniumhq.selenium</groupId>
-            <artifactId>selenium-support</artifactId>
-        </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/pages/Page.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/pages/Page.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/pages/Page.java
index 3e6534a..5319b6d 100644
--- a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/pages/Page.java
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/pages/Page.java
@@ -48,6 +48,9 @@ public abstract class Page {
         url = helper.getClusterHelper().getHostname();
     }
 
+    public Page(WebDriver driver) {
+        this.driver = driver;
+    }
     /**
      * Go to page in browser.
      */

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/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
new file mode 100644
index 0000000..eaaeba2
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/AbstractSearchPage.java
@@ -0,0 +1,56 @@
+/**
+ * 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.enumsAndConstants.MerlinConstants;
+import org.apache.falcon.regression.ui.pages.Page;
+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.PageFactory;
+
+/** Parent page object for all the search ui pages. */
+public abstract class AbstractSearchPage extends Page {
+
+    public static final String UI_URL = MerlinConstants.PRISM_URL;
+
+    public AbstractSearchPage(WebDriver driver) {
+        super(driver);
+        pageHeader = PageFactory.initElements(driver, PageHeader.class);
+    }
+
+    private PageHeader pageHeader;
+
+    @FindBy(className = "mainUIView")
+    private WebElement mainUI;
+
+    public PageHeader getPageHeader() {
+        return pageHeader;
+    }
+
+    protected WebElement getParentElement(WebElement element) {
+        return element.findElement(By.xpath(".."));
+    }
+
+    /**
+     * A rough check to make sure that we are indeed on the correct page.
+     */
+    public abstract void checkPage();
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
new file mode 100644
index 0000000..3701d22
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/LoginPage.java
@@ -0,0 +1,117 @@
+/**
+ * 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.apache.log4j.Logger;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+import org.openqa.selenium.support.PageFactory;
+import org.testng.Assert;
+
+/** Page object for the Login Page. */
+public class LoginPage extends AbstractSearchPage {
+    private static final Logger LOGGER = Logger.getLogger(LoginPage.class);
+    public static final String UI_DEFAULT_USER = "ambari-qa";
+    public static final String UI_DEFAULT_PASSWD = "admin";
+
+    public LoginPage(WebDriver driver) {
+        super(driver);
+    }
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "login")
+    })
+    protected WebElement loginElem;
+
+    public static LoginPage open(WebDriver driver) {
+        driver.get(UI_URL);
+        return PageFactory.initElements(driver, LoginPage.class);
+    }
+
+    private WebElement getUserTextBox() {
+        return loginElem.findElement(By.xpath("//input[@name='user']"));
+    }
+
+    public void appendToUserName(String text) {
+        getUserTextBox().sendKeys(text);
+    }
+
+    public String getUserVisibleWarning() {
+        final WebElement userTextBox = getUserTextBox();
+
+        final WebElement userWarnLabel = getParentElement(userTextBox).findElement(
+            By.xpath("//label[@class='custom-danger validationMessageGral']"));
+        if (userWarnLabel.isDisplayed()) {
+            return userWarnLabel.getText();
+        }
+        return "";
+    }
+
+    private WebElement getPasswdTextBox() {
+        return loginElem.findElement(By.xpath("//input[@name='password']"));
+    }
+
+    public void appendToPasswd(String text) {
+        getPasswdTextBox().sendKeys(text);
+    }
+    public String getPasswdVisibleWarning() {
+        final WebElement passwdWarnLabel = getParentElement(getPasswdTextBox()).findElements(
+            By.xpath("//label[@class='custom-danger validationMessageGral']")).get(1);
+        if (passwdWarnLabel.isDisplayed()) {
+            return passwdWarnLabel.getText();
+        }
+        return "";
+    }
+
+    /** Try to login by pressing the login button. */
+    public void tryLogin() {
+        LOGGER.info("Trying to login.");
+        final WebElement loginButton = loginElem.findElement(By.id("login.submit"));
+        UIAssert.assertDisplayed(loginButton, "Login button");
+        loginButton.click();
+    }
+
+    /** Login successfully and take to the next page i.e. search page. */
+    public SearchPage doDefaultLogin() {
+        getUserTextBox().clear();
+        getPasswdTextBox().clear();
+        appendToUserName(UI_DEFAULT_USER);
+        appendToPasswd(UI_DEFAULT_PASSWD);
+        tryLogin();
+        LOGGER.info("Search page should have opened.");
+        final SearchPage searchPage = PageFactory.initElements(driver, SearchPage.class);
+        searchPage.checkPage();
+        final PageHeader searchHeader = searchPage.getPageHeader();
+        searchHeader.checkLoggedIn();
+        Assert.assertEquals(searchHeader.getLoggedInUser(), LoginPage.UI_DEFAULT_USER,
+            "Unexpected user is displayed");
+        return searchPage;
+    }
+
+    @Override
+    public void checkPage() {
+        UIAssert.assertDisplayed(loginElem, "Cluster box");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewClusterPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewClusterPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewClusterPage.java
new file mode 100644
index 0000000..fa8349b
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewClusterPage.java
@@ -0,0 +1,44 @@
+/**
+ * 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 Cluster creation page. */
+public class NewClusterPage extends AbstractSearchPage {
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "clusterForm")
+    })
+    private WebElement clusterBox;
+
+    public NewClusterPage(WebDriver driver) {
+        super(driver);
+    }
+
+    @Override
+    public void checkPage() {
+        UIAssert.assertDisplayed(clusterBox, "Cluster box");
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewFeedPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewFeedPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewFeedPage.java
new file mode 100644
index 0000000..4863da3
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewFeedPage.java
@@ -0,0 +1,44 @@
+/**
+ * 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 Feed creation page. */
+public class NewFeedPage extends AbstractSearchPage {
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "feedForm")
+    })
+    private WebElement feedBox;
+
+    public NewFeedPage(WebDriver driver) {
+        super(driver);
+    }
+
+    @Override
+    public void checkPage() {
+        UIAssert.assertDisplayed(feedBox, "Feed box");
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewMirrorPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewMirrorPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewMirrorPage.java
new file mode 100644
index 0000000..2772f54
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewMirrorPage.java
@@ -0,0 +1,44 @@
+/**
+ * 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 Mirror creation page. */
+public class NewMirrorPage extends AbstractSearchPage {
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "formPage")
+    })
+    private WebElement mirrorBox;
+
+    public NewMirrorPage(WebDriver driver) {
+        super(driver);
+    }
+
+    @Override
+    public void checkPage() {
+        UIAssert.assertDisplayed(mirrorBox, "Mirror box");
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/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
new file mode 100644
index 0000000..f7d5bad
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/NewProcessPage.java
@@ -0,0 +1,44 @@
+/**
+ * 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/13650648/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
new file mode 100644
index 0000000..b9d766f
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/PageHeader.java
@@ -0,0 +1,231 @@
+/**
+ * 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.enumsAndConstants.MerlinConstants;
+import org.apache.falcon.regression.core.util.AssertUtil;
+import org.apache.falcon.regression.core.util.UIAssert;
+import org.apache.log4j.Logger;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+import org.openqa.selenium.support.PageFactory;
+import org.testng.Assert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Page object for header of the search ui pages. */
+public class PageHeader {
+    private static final Logger LOGGER = Logger.getLogger(PageHeader.class);
+
+    protected WebDriver driver;
+
+    public PageHeader(WebDriver driver) {
+        this.driver = driver;
+    }
+
+    @FindBy(className = "navbar")
+    private WebElement header;
+
+    @FindBys({
+        @FindBy(className = "navbar"),
+        @FindBy(className = "logoTitle")
+    })
+    private WebElement homeButton;
+
+    @FindBys({
+        @FindBy(className = "navbar"),
+        @FindBy(className = "logoTitle"),
+        @FindBy(className = "falconLogo")
+    })
+    private WebElement falconLogo;
+
+    @FindBys({
+        @FindBy(className = "navbar"),
+        @FindBy(className = "loginHeaderBox")
+    })
+    private WebElement loginHeaderBox;
+
+    @FindBys({
+        @FindBy(className = "navbar"),
+        @FindBy(className = "createNavWrapper")
+    })
+    private WebElement createEntityBox;
+
+    @FindBy(id = "cluster.create")
+    private WebElement clusterCreateButton;
+
+    @FindBy(id = "feed.create")
+    private WebElement feedCreateButton;
+
+    @FindBy(id = "process.create")
+    private WebElement processCreateButton;
+
+    @FindBy(id = "dataset.create")
+    private WebElement mirrorCreateButton;
+
+    @FindBys({
+        @FindBy(className = "navbar"),
+        @FindBy(className = "uploadNavWrapper")
+    })
+    private WebElement uploadEntityBox;
+
+    @FindBys({
+        @FindBy(className = "navbar"),
+        @FindBy(className = "uploadNavWrapper"),
+        @FindBy(className = "btn-file")
+    })
+    private WebElement uploadEntityButton;
+
+
+    public WebElement getHomeButton() {
+        return homeButton;
+    }
+
+    public void checkLoggedIn() {
+        Assert.assertEquals(getLogoutButton().getText(), "Logout",
+            "Unexpected text on logout button");
+    }
+
+    public void checkLoggedOut() {
+        UIAssert.assertNotDisplayed(getLogoutButton(), "logout button");
+    }
+
+    /**
+     * Check header and make sure all the buttons/links are working correctly. Handles both
+     * logged in and logged out scenarios.
+     */
+    public void checkHeader() {
+        //home button is always displayed
+        UIAssert.assertDisplayed(homeButton, "falcon logo");
+        Assert.assertEquals(homeButton.getText(), "Falcon", "Unexpected home button text");
+        UIAssert.assertDisplayed(falconLogo, "falcon logo");
+        final String oldUrl = driver.getCurrentUrl();
+
+        homeButton.click();
+        Assert.assertTrue(getHomeUrls().contains(driver.getCurrentUrl()),
+            "home button navigate to: " + driver.getCurrentUrl() + " instead of: " + getHomeUrls());
+        driver.get(oldUrl);
+
+        //displayed if user is logged in: create entity buttons, upload entity button, username
+        if (getLogoutButton().isDisplayed()) {
+            //checking create entity box
+            UIAssert.assertDisplayed(createEntityBox, "Create entity box");
+            final WebElement createEntityLabel = createEntityBox.findElement(By.tagName("h4"));
+            Assert.assertEquals(createEntityLabel.getText(), "Create an entity",
+                "Unexpected create entity text");
+            doCreateCluster();
+            driver.get(oldUrl);
+            doCreateFeed();
+            driver.get(oldUrl);
+            doCreateProcess();
+            driver.get(oldUrl);
+            doCreateMirror();
+            driver.get(oldUrl);
+
+            //checking upload entity part
+            UIAssert.assertDisplayed(uploadEntityBox, "Create entity box");
+            final WebElement uploadEntityLabel = uploadEntityBox.findElement(By.tagName("h4"));
+            Assert.assertEquals(uploadEntityLabel.getText(), "Upload an entity",
+                "Unexpected upload entity text");
+            UIAssert.assertDisplayed(uploadEntityButton, "Create entity box");
+            Assert.assertEquals(uploadEntityButton.getText(), "Browse for the XML file",
+                "Unexpected text on upload entity button");
+            //checking if logged-in username is displayed
+            AssertUtil.assertNotEmpty(getLoggedInUser(), "Expecting logged-in username.");
+        }
+
+        //help link is always displayed
+        final WebElement helpLink = loginHeaderBox.findElement(By.tagName("a"));
+        UIAssert.assertDisplayed(helpLink, "help link");
+        Assert.assertEquals(helpLink.getText(), "Help", "Help link expected to have text 'Help'");
+        helpLink.click();
+        Assert.assertEquals(driver.getCurrentUrl(), MerlinConstants.HELP_URL,
+            "Unexpected help url");
+        driver.get(oldUrl);
+    }
+
+    public NewClusterPage doCreateCluster() {
+        UIAssert.assertDisplayed(clusterCreateButton, "Cluster create button");
+        Assert.assertEquals(clusterCreateButton.getText(), "Cluster",
+            "Unexpected text on create cluster button");
+        clusterCreateButton.click();
+        final NewClusterPage clusterPage = PageFactory.initElements(driver, NewClusterPage.class);
+        clusterPage.checkPage();
+        return clusterPage;
+    }
+
+    public NewFeedPage doCreateFeed() {
+        UIAssert.assertDisplayed(feedCreateButton, "Feed create button");
+        Assert.assertEquals(feedCreateButton.getText(), "Feed",
+            "Unexpected text on create feed button");
+        feedCreateButton.click();
+        final NewFeedPage feedPage = PageFactory.initElements(driver, NewFeedPage.class);
+        feedPage.checkPage();
+        return feedPage;
+    }
+
+    public NewProcessPage 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);
+        processPage.checkPage();
+        return processPage;
+    }
+
+    public NewMirrorPage doCreateMirror() {
+        UIAssert.assertDisplayed(mirrorCreateButton, "Mirror create button");
+        Assert.assertEquals(mirrorCreateButton.getText(), "Mirror",
+            "Unexpected text on create mirror button");
+        mirrorCreateButton.click();
+        final NewMirrorPage mirrorPage = PageFactory.initElements(driver, NewMirrorPage.class);
+        mirrorPage.checkPage();
+        return mirrorPage;
+    }
+
+    private List<String> getHomeUrls() {
+        List<String> urls = new ArrayList<>();
+        String homeUrl = MerlinConstants.PRISM_URL;
+        urls.add(homeUrl);
+        urls.add(homeUrl.replaceAll("/$", "") + "/#/");
+        return urls;
+    }
+
+    public String getLoggedInUser() {
+        return loginHeaderBox.findElement(By.tagName("div")).getText();
+    }
+
+    private WebElement getLogoutButton() {
+        return loginHeaderBox.findElement(By.tagName("button"));
+    }
+
+    public LoginPage doLogout() {
+        LOGGER.info("Going to logout.");
+        getLogoutButton().click();
+        final LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
+        loginPage.checkPage();
+        return loginPage;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/SearchPage.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/SearchPage.java b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/SearchPage.java
new file mode 100644
index 0000000..8c3ae71
--- /dev/null
+++ b/falcon-regression/merlin/src/main/java/org/apache/falcon/regression/ui/search/SearchPage.java
@@ -0,0 +1,234 @@
+/**
+ * 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.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+import org.testng.Assert;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/** Page object for the Search Page. */
+public class SearchPage extends AbstractSearchPage {
+    public SearchPage(WebDriver driver) {
+        super(driver);
+    }
+
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "searchBoxContainer")
+    })
+    private WebElement searchBlock;
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "dashboardBox")
+    })
+    private WebElement resultBlock;
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "dashboardBox"),
+        @FindBy(tagName = "thead")
+    })
+    private WebElement resultHeader;
+
+    @FindBys({
+        @FindBy(className = "mainUIView"),
+        @FindBy(className = "dashboardBox"),
+        @FindBy(className = "buttonRow")
+    })
+    private WebElement resultButtons;
+
+    private List<WebElement> getSearchResultElements() {
+        return resultBlock.findElements(By.className("entityRow"));
+    }
+
+    public List<SearchResult> getSearchResults() {
+        List<SearchResult> searchResults = new ArrayList<>();
+        for (WebElement oneResultElement : getSearchResultElements()) {
+            final List<WebElement> resultParts = oneResultElement.findElements(By.tagName("td"));
+            final String entityName = resultParts.get(1).getText();
+            final SearchResult searchResult = SearchResult.create(entityName);
+
+            final String[] allClasses = oneResultElement.getAttribute("class").split(" ");
+            final String classOfSelectedRow = "rowSelected";
+            if (Arrays.asList(allClasses).contains(classOfSelectedRow)) {
+                searchResult.withChecked(true);
+            }
+
+            final String tags = resultParts.get(2).getText();
+            searchResult.withTags(tags);
+
+            final String clusterName = resultParts.get(3).getText();
+            searchResult.withClusterName(clusterName);
+
+            final String type = resultParts.get(4).getText();
+            searchResult.withType(type);
+
+            final String status = resultParts.get(5).getText();
+            searchResult.withStatus(status);
+            searchResults.add(searchResult);
+        }
+        return searchResults;
+    }
+
+    @Override
+    public void checkPage() {
+        UIAssert.assertDisplayed(searchBlock, "Cluster box");
+    }
+
+    private WebElement getSearchBox() {
+        return searchBlock.findElement(By.className("input"));
+    }
+
+    public List<SearchResult> doSearch(String searchString) {
+        getSearchBox().sendKeys(searchString + "\n");
+        UIAssert.assertDisplayed(resultBlock, "Search result block");
+        return getSearchResults();
+    }
+
+    public SearchQuery getSearchQuery() {
+        final WebElement queryGroup = searchBlock.findElement(By.className("tag-list"));
+        final List<WebElement> queryParts = queryGroup.findElements(By.tagName("li"));
+        if (queryParts.size() == 0) {
+            return SearchQuery.create(null);
+        } else {
+            final WebElement namePart = queryParts.remove(0);
+            final WebElement nameLabel = namePart.findElement(By.tagName("strong"));
+            Assert.assertEquals(nameLabel.getText(), "NAME: ", "Name label of query");
+            final WebElement nameElem = namePart.findElement(By.tagName("span"));
+            SearchQuery searchQuery = SearchQuery.create(nameElem.getText());
+            for (WebElement tagPart : queryParts) {
+                final WebElement tagLabel = tagPart.findElement(By.tagName("strong"));
+                Assert.assertEquals(tagLabel.getText(), "TAG: ", "Tag label of query");
+                final WebElement tagElem = tagPart.findElement(By.tagName("span"));
+                searchQuery.withTag(tagElem.getText());
+            }
+            return searchQuery;
+        }
+    }
+
+    public void checkNoResult() {
+        UIAssert.assertNotDisplayed(resultBlock, "Search result block");
+    }
+
+    /** Class representing search query displayed in the search box. */
+    public static final class SearchQuery {
+        private final String name;
+
+        private final List<String> tags = new ArrayList<>();
+
+        private SearchQuery(String name) {
+            this.name = name;
+        }
+
+        public static SearchQuery create(String name) {
+            return new SearchQuery(name);
+        }
+
+        public SearchQuery withTag(String tag) {
+            tags.add(tag);
+            return this;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public List<String> getTags() {
+            return tags;
+        }
+    }
+
+    /** Class representing search result displayed on the entity table page. */
+    public static final class SearchResult {
+        private boolean isChecked = false;
+        private String entityName;
+        private String tags = "";
+        private String clusterName;
+        private String type;
+        private String status;
+
+        public static SearchResult create(String entityName) {
+            return new SearchResult(entityName);
+        }
+
+        public SearchResult withChecked(boolean pIsChecked) {
+            this.isChecked = pIsChecked;
+            return this;
+        }
+
+        private SearchResult(String entityName) {
+            this.entityName = entityName;
+        }
+
+        public SearchResult withTags(String pTags) {
+            this.tags = pTags;
+            return this;
+        }
+
+        public SearchResult withClusterName(String pClusterName) {
+            this.clusterName = pClusterName;
+            return this;
+        }
+
+        public SearchResult withType(String pType) {
+            this.type = pType;
+            return this;
+        }
+
+        public SearchResult withStatus(String pStatus) {
+            this.status = pStatus;
+            return this;
+        }
+
+        public boolean isChecked() {
+            return isChecked;
+        }
+
+        public String getEntityName() {
+            return entityName;
+        }
+
+        public String getTags() {
+            return tags;
+        }
+
+        public String getClusterName() {
+            return clusterName;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public String getStatus() {
+            return status;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
new file mode 100644
index 0000000..b752a86
--- /dev/null
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/HomePageTest.java
@@ -0,0 +1,84 @@
+/**
+ * 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.falcon.regression.core.bundle.Bundle;
+import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.falcon.regression.core.util.AssertUtil;
+import org.apache.falcon.regression.core.util.BundleUtil;
+import org.apache.falcon.regression.testHelper.BaseUITestClass;
+import org.apache.falcon.regression.ui.search.LoginPage;
+import org.apache.falcon.regression.ui.search.SearchPage;
+import org.apache.log4j.Logger;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+/** UI tests for Search UI Homepage. */
+@Test(groups = "search-ui")
+public class HomePageTest extends BaseUITestClass {
+    private static final Logger LOGGER = Logger.getLogger(HomePageTest.class);
+    private SearchPage homePage = null;
+
+    @BeforeMethod(alwaysRun = true)
+    public void setup() {
+        openBrowser();
+        homePage = LoginPage.open(getDriver()).doDefaultLogin();
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws IOException {
+        removeTestClassEntities();
+        closeBrowser();
+    }
+
+    @Test
+    public void testHeader() throws Exception {
+        homePage.getPageHeader().checkHeader();
+    }
+
+    @Test
+    public void testNavigationToEntitiesTable() throws Exception {
+        homePage.checkNoResult();
+        bundles[0] = BundleUtil.readELBundle();
+        ColoHelper cluster = servers.get(0);
+        bundles[0] = new Bundle(bundles[0], cluster);
+        bundles[0].generateUniqueBundle(this);
+        String pigTestDir = cleanAndGetTestDir();
+        String inputPath = pigTestDir + "/input" + MINUTE_DATE_PATTERN;
+        bundles[0].setInputFeedDataPath(inputPath);
+        bundles[0].submitAndScheduleFeed();
+        final List<SearchPage.SearchResult> searchResults = homePage.doSearch("*");
+        Assert.assertEquals(searchResults.size(), 1, "Expecting one search results");
+    }
+
+    @Test
+    public void testSearchBoxInitialConditions() throws Exception {
+        homePage.checkNoResult();
+        AssertUtil.assertEmpty(homePage.getSearchQuery().getName(), "Expecting blank search box");
+        AssertUtil.assertEmpty(homePage.getSearchQuery().getTags(), "Expecting blank search box");
+        final List<SearchPage.SearchResult> searchResults = homePage.getSearchResults();
+        Assert.assertEquals(searchResults.size(), 0, "Expecting no search results");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/LoginTest.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/LoginTest.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/LoginTest.java
new file mode 100644
index 0000000..a40fe20
--- /dev/null
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/searchUI/LoginTest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.falcon.regression.core.util.AssertUtil;
+import org.apache.falcon.regression.testHelper.BaseUITestClass;
+import org.apache.falcon.regression.ui.search.LoginPage;
+import org.apache.falcon.regression.ui.search.SearchPage;
+import org.apache.log4j.Logger;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+/** UI tests for login/logout. */
+@Test(groups = "search-ui")
+public class LoginTest extends BaseUITestClass {
+    private static final Logger LOGGER = Logger.getLogger(LoginTest.class);
+    private LoginPage loginPage = null;
+
+    @BeforeMethod(alwaysRun = true)
+    public void setup() {
+        openBrowser();
+        loginPage = LoginPage.open(getDriver());
+        loginPage.getPageHeader().checkLoggedOut();
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws IOException {
+        closeBrowser();
+    }
+
+    @Test
+    public void testLoginWithoutUser() throws Exception {
+        AssertUtil.assertEmpty(loginPage.getUserVisibleWarning(), "Unexpected user warning.");
+
+        loginPage.tryLogin();
+
+        Assert.assertEquals(loginPage.getUserVisibleWarning(), "Please enter your user name.",
+            "Unexpected warning displayed when logging in without user.");
+    }
+
+    @Test
+    public void testValidUserNames() throws Exception {
+        AssertUtil.assertEmpty(loginPage.getUserVisibleWarning(), "Unexpected user warning.");
+        for (String str : "some_user".split("")) {
+            loginPage.appendToUserName(str);
+        }
+        AssertUtil.assertEmpty(loginPage.getUserVisibleWarning(), "Unexpected user warning.");
+    }
+
+    @DataProvider
+    public Object[][] getInvalidNames() {
+        return new Object[][]{
+            {"some@user"},
+            {"some" + "\u20AC" + "user"},
+            {"some user"},
+        };
+    }
+
+    @Test(dataProvider = "getInvalidNames")
+    public void testInvalidUserNames(final String userName) throws Exception {
+        AssertUtil.assertEmpty(loginPage.getUserVisibleWarning(), "Unexpected user warning.");
+        for (String str : userName.split("")) {
+            loginPage.appendToUserName(str);
+        }
+        Assert.assertEquals(loginPage.getUserVisibleWarning(), "The User has an invalid format.",
+            "Unexpected user warning.");
+    }
+
+    @Test
+    public void testLoginWithoutPassword() throws Exception {
+        loginPage.appendToUserName("some-user");
+
+        loginPage.tryLogin();
+
+        Assert.assertEquals(loginPage.getPasswdVisibleWarning(), "Please enter your password.");
+    }
+
+    @Test
+    public void testLoginSuccessfully() throws Exception {
+        SearchPage searchPage = loginPage.doDefaultLogin();
+        searchPage.checkPage();
+
+        final LoginPage newLoginPage = searchPage.getPageHeader().doLogout();
+        newLoginPage.getPageHeader().checkLoggedOut();
+    }
+
+    @Test
+    public void testHeader() throws Exception {
+        loginPage.getPageHeader().checkHeader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/13650648/falcon-regression/pom.xml
----------------------------------------------------------------------
diff --git a/falcon-regression/pom.xml b/falcon-regression/pom.xml
index 2b1d15a..1490313 100644
--- a/falcon-regression/pom.xml
+++ b/falcon-regression/pom.xml
@@ -171,13 +171,13 @@
             <dependency>
                 <groupId>org.apache.httpcomponents</groupId>
                 <artifactId>httpclient</artifactId>
-                <version>4.2.3</version>
+                <version>4.4.1</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.httpcomponents</groupId>
                 <artifactId>httpcore</artifactId>
-                <version>4.2.3</version>
+                <version>4.4.1</version>
             </dependency>
 
             <dependency>
@@ -214,18 +214,23 @@
             <dependency>
                 <groupId>org.seleniumhq.selenium</groupId>
                 <artifactId>selenium-firefox-driver</artifactId>
-                <version>2.41.0</version>
+                <version>2.45.0</version>
             </dependency>
             <dependency>
                 <groupId>org.seleniumhq.selenium</groupId>
                 <artifactId>selenium-support</artifactId>
-                <version>2.41.0</version>
+                <version>2.45.0</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-exec</artifactId>
                 <version>1.2</version>
             </dependency>
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>18.0</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>