/**
* 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.TimeUtil;
import org.apache.falcon.regression.core.util.UIAssert;
import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import java.io.IOException;
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 = "uploadNavWrapper"),
})
private WebElement uploadEntityBox;
@FindBys({
@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 SearchPage gotoHome() {
homeButton.click();
final SearchPage searchPage = PageFactory.initElements(driver, SearchPage.class);
searchPage.checkPage();
final PageHeader searchHeader = searchPage.getPageHeader();
if (!MerlinConstants.IS_SECURE) {
searchHeader.checkLoggedIn();
Assert.assertEquals(searchHeader.getLoggedInUser(), LoginPage.UI_DEFAULT_USER,
"Unexpected user is displayed");
}
return searchPage;
}
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 WebElement helpLink = loginHeaderBox.findElement(By.tagName("a"));
UIAssert.assertDisplayed(helpLink, "help link");
final String oldUrl = driver.getCurrentUrl();
//displayed if user is logged in: create entity buttons, upload entity button, username
if (MerlinConstants.IS_SECURE || 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");
//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");
Assert.assertEquals(uploadEntityButton.getText(), "Browse for the XML file",
"Unexpected text on upload entity button");
//checking if logged-in username is displayed
if (!MerlinConstants.IS_SECURE) {
UIAssert.assertDisplayed(getLogoutButton(), "Logout button");
AssertUtil.assertNotEmpty(getLoggedInUser(), "Expecting logged-in username.");
}
//create button navigation
doCreateCluster();
driver.get(oldUrl);
doCreateFeed();
driver.get(oldUrl);
doCreateProcess();
driver.get(oldUrl);
driver.get(oldUrl);
}
//home button navigation
homeButton.click();
Assert.assertTrue(getHomeUrls().contains(driver.getCurrentUrl()),
"home button navigate to: " + driver.getCurrentUrl() + " instead of: " + getHomeUrls());
driver.get(oldUrl);
//help link navigation
Assert.assertEquals(helpLink.getText(), "Help", "Help link expected to have text 'Help'");
clickLink(helpLink);
int helpPageloadTimeoutThreshold = 30;
new WebDriverWait(driver, helpPageloadTimeoutThreshold).until(
ExpectedConditions.stalenessOf(helpLink));
Assert.assertEquals(driver.getCurrentUrl(), MerlinConstants.HELP_URL,
"Unexpected help url");
driver.get(oldUrl);
}
/**
* Useful in cases when selenium fails to click a link due to it's bugs.
*/
private void clickLink(WebElement link) {
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", link);
}
public void uploadXml(String filePath) throws IOException {
final WebElement uploadEntityTextBox = uploadEntityBox.findElement(By.id("files"));
uploadEntityTextBox.sendKeys(filePath);
//wait for alert
driver.findElements(
By.xpath("//div[@class='messages notifs' and contains(@style,'opacity') and not(contains(@style,'1;'))]"));
}
public ClusterWizardPage doCreateCluster() {
UIAssert.assertDisplayed(clusterCreateButton, "Cluster create button");
Assert.assertEquals(clusterCreateButton.getText(), "Cluster",
"Unexpected text on create cluster button");
clusterCreateButton.click();
final ClusterWizardPage clusterPage = PageFactory.initElements(driver, ClusterWizardPage.class);
clusterPage.checkPage();
return clusterPage;
}
public FeedWizardPage doCreateFeed() {
UIAssert.assertDisplayed(feedCreateButton, "Feed create button");
Assert.assertEquals(feedCreateButton.getText(), "Feed",
"Unexpected text on create feed button");
feedCreateButton.click();
final FeedWizardPage feedPage = PageFactory.initElements(driver, FeedWizardPage.class);
feedPage.checkPage();
return feedPage;
}
public ProcessWizardPage doCreateProcess() {
UIAssert.assertDisplayed(processCreateButton, "Process create button");
Assert.assertEquals(processCreateButton.getText(), "Process",
"Unexpected text on create process button");
processCreateButton.click();
final ProcessWizardPage processPage = PageFactory.initElements(driver, ProcessWizardPage.class);
processPage.checkPage();
return processPage;
}
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.findElements(By.xpath("button[@ng-click='logOut()']")).get(0);
}
private WebElement getNotificationButton() {
return loginHeaderBox.findElements(By.xpath("button[@ng-click='notify()']")).get(0);
}
/**
* Validates number of notifications contained by notification bar and last notification message.
*/
public void validateNotificationCountAndCheckLast(int count, String message) {
WebElement notificationButton = getNotificationButton();
notificationButton.click();
waitForAngularToFinish();
// Test notifications dropdown visibility
WebElement notificationDropdown = notificationButton.findElement(By.className("messages"));
Assert.assertTrue(notificationDropdown.getAttribute("style").contains("display: block;"),
"Notifications are not visible.");
// Test validity of number of notifications
List<WebElement> notifications = notificationDropdown.findElements(By.xpath("div"));
Assert.assertEquals(notifications.size() - 1, count, "Invalid notification count.");
// Test validity of last notification
String lastNotification = notifications.get(0).getText();
Assert.assertTrue(lastNotification.contains(message), "Invalid last notification text.");
}
public LoginPage doLogout() {
LOGGER.info("Going to logout.");
getLogoutButton().click();
final LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
loginPage.checkPage();
return loginPage;
}
protected void waitForAngularToFinish() {
final String javaScript = "return (window.angular != null) && "
+ "(angular.element(document).injector() != null) && "
+ "(angular.element(document).injector().get('$http').pendingRequests.length === 0)";
boolean isLoaded = false;
for (int i = 0; i < AbstractSearchPage.PAGELOAD_TIMEOUT_THRESHOLD && !isLoaded; i++) {
final Object output = ((JavascriptExecutor) driver).executeScript(javaScript);
isLoaded = Boolean.valueOf(output.toString());
LOGGER.info(i+1 + ". waiting on angular to finish.");
TimeUtil.sleepSeconds(1);
}
LOGGER.info("angular is done continuing...");
}
}