/** * 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.ImmutableMap; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.WordUtils; import org.apache.falcon.entity.v0.Frequency; import org.apache.falcon.entity.v0.feed.Cluster; import org.apache.falcon.entity.v0.feed.LocationType; import org.apache.falcon.entity.v0.feed.Property; import org.apache.falcon.entity.v0.process.Input; import org.apache.falcon.entity.v0.process.Output; import org.apache.falcon.entity.v0.process.Retry; import org.apache.falcon.regression.Entities.FeedMerlin; import org.apache.falcon.regression.Entities.ProcessMerlin; import org.apache.falcon.regression.core.util.TimeUtil; import org.apache.falcon.regression.core.util.UIAssert; import org.apache.falcon.resource.InstancesResult; import org.apache.log4j.Logger; import org.openqa.selenium.By; import org.openqa.selenium.Keys; 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.Select; import org.testng.asserts.SoftAssert; 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.Map; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; /** * Class representation of Search UI entity page. */ public class EntityPage extends AbstractSearchPage { private static final Logger LOGGER = Logger.getLogger(EntityPage.class); /** * Possible instance actions available on entity page. */ public enum InstanceAction { Log, Resume, Rerun, Suspend, Kill } public EntityPage(WebDriver driver) { super(driver); } private WebElement getEntityTitle() { final WebElement title = driver.findElement(By.id("entity-title")); UIAssert.assertDisplayed(title, "entity title"); return title; } @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "dependencies-graph") }) private WebElement dependencyBox; @FindBys({ @FindBy(className = "mainUIView"), @FindBy(xpath = "(.//*[contains(@class, 'detailsBox')])[2]") }) private WebElement instanceListBox; @FindBys({ @FindBy(className = "mainUIView"), @FindBy(className = "summaryBox") }) private WebElement propertiesBlock; public String getEntityName() { UIAssert.assertDisplayed(getEntityTitle(), "Entity title"); return getEntityTitle().getText().split(" ")[0]; } @Override public void checkPage() { UIAssert.assertDisplayed(dependencyBox, "Dependency box"); UIAssert.assertDisplayed(instanceListBox, "Instance list box"); UIAssert.assertDisplayed(propertiesBlock, "Summary box"); } public EntityPage refreshPage() { final String entityName = getEntityName(); SearchPage searchPage = getPageHeader().gotoHome(); return searchPage.openEntityPage(entityName); } public void checkFeedProperties(FeedMerlin feed) { openProperties(); final WebElement propertiesBox = propertiesBlock.findElement(By.xpath("//div[@ui-view='feedSummary']")); UIAssert.assertDisplayed(propertiesBox, "Properties box"); //all the parts of the entity properties final List<WebElement> propertyParts = propertiesBox.findElements(By.xpath("./div")); //First set of properties final WebElement generalBox = propertyParts.get(0); final List<WebElement> generalParts = generalBox.findElements(By.xpath("./div")); SoftAssert softAssert = new SoftAssert(); //General softAssert.assertEquals(generalParts.get(0).getText(), "General", "Unexpected heading"); final List<WebElement> nameAndDesc = generalParts.get(1).findElements(By.xpath("./div")); softAssert.assertEquals(nameAndDesc.get(0).getText(), "Name: " + feed.getName(), "Unexpected feed name in properties."); softAssert.assertEquals(nameAndDesc.get(1).getText(), "Description: " + feed.getDescription(), "Unexpected description in properties."); //Tags softAssert.assertEquals(generalParts.get(2).getText(), "Tags", "Unexpected heading"); softAssert.assertEquals(generalParts.get(3).getText(), StringUtils.trimToEmpty(feed.getTags()), "Unexpected tags"); //Groups softAssert.assertEquals(generalParts.get(4).getText(), "Groups", "Unexpected heading"); softAssert.assertEquals(generalParts.get(5).getText(), StringUtils.trimToEmpty(feed.getGroups()), "Unexpected groups"); //Access Control list softAssert.assertEquals(generalParts.get(6).getText(), "Access Control List", "Unexpected heading"); final List<WebElement> ownerGrpPerm = generalParts.get(7).findElements(By.xpath("./div")); softAssert.assertEquals(ownerGrpPerm.get(0).getText(), "Owner: " + feed.getACL().getOwner(), "Unexpected owner"); softAssert.assertEquals(ownerGrpPerm.get(1).getText(), "Group: " + feed.getACL().getGroup(), "Unexpected group"); softAssert.assertEquals(ownerGrpPerm.get(2).getText(), "Permissions: " + feed.getACL().getPermission(), "Unexpected permission"); //Schema softAssert.assertEquals(generalParts.get(8).getText(), "Schema", "Unexpected heading for general properties"); final List<WebElement> locAndProvider = generalParts.get(9).findElements(By.xpath("./div")); softAssert.assertEquals(locAndProvider.get(0).getText(), "Location: " + feed.getSchema().getLocation(), "Unexpected schema locations"); softAssert.assertEquals(locAndProvider.get(1).getText(), "Provider: " + feed.getSchema().getProvider(), "Unexpected schema provider"); //Properties softAssert.assertEquals(generalParts.get(10).getText(), "Properties", "Unexpected heading for general properties"); final List<WebElement> freqLateAvail = generalParts.get(11).findElements(By.xpath("./div")); final Frequency feedFrequency = feed.getFrequency(); softAssert.assertEquals(freqLateAvail.get(0).getText(), String.format("Frequency: Every %s %s", feedFrequency.getFrequency(), feedFrequency.getTimeUnit()), "Unexpected frequency"); final Frequency feedLateCutoff = feed.getLateArrival().getCutOff(); softAssert.assertEquals(freqLateAvail.get(1).getText(), String.format("Late Arrival: Up to %s %s", feedLateCutoff.getFrequency(), feedLateCutoff.getTimeUnit()), "Unexpected late arrival"); softAssert.assertEquals(freqLateAvail.get(2).getText(), String.format("Availability Flag:%s", StringUtils.trimToEmpty(feed.getAvailabilityFlag())), "Unexpected availability flag"); final List<WebElement> propertyElements = generalParts.get(12).findElements(By.xpath("./div")); List<String> displayedPropStr = new ArrayList<>(); for (WebElement webElement : propertyElements) { displayedPropStr.add(webElement.getText()); } Collections.sort(displayedPropStr); final List<String> expectedPropStr = getFeedPropString(feed); softAssert.assertEquals(displayedPropStr, expectedPropStr, "Feed properties & displayed properties don't match. Expected: " + expectedPropStr + " Actual: " + displayedPropStr); //Storage type softAssert.assertEquals(generalParts.get(13).getText(), "Default Storage Type:", "Unexpected label for storage type."); if (feed.getLocations() != null && feed.getLocations().getLocations() != null && feed.getLocations().getLocations().size() > 0) { softAssert.assertEquals(generalParts.get(13).getText(), "File System", "Unexpected storage type for feed."); } else { softAssert.fail("Need to add handler for other feed types."); } //Feed locations - Data followed by Stats followed by Meta softAssert.assertEquals(generalParts.get(14).getText(), "Default Location:", "Unexpected label for default location."); softAssert.assertEquals(generalParts.get(15).getText(), "Data\n" + feed.getFeedPath(LocationType.DATA), "Unexpected label for feed data label"); softAssert.assertEquals(generalParts.get(16).getText(), "Stats\n" + feed.getFeedPath(LocationType.STATS), "Unexpected label for feed stats label"); softAssert.assertEquals(generalParts.get(17).getText(), "Meta\n" + feed.getFeedPath(LocationType.META), "Unexpected label for feed mata label"); //Second set of properties details with Source Cluster Properties final WebElement clustersBox = propertyParts.get(1); final List<WebElement> displayedClusters = clustersBox.findElements(By.xpath("./div")); final List<Cluster> feedClusters = feed.getClusters().getClusters(); //test needs to be fixed when we have support for more than one feed cluster softAssert.assertEquals(feedClusters.size(), 1, "Current UI has support for only one feed cluster."); checkFeedCluster(displayedClusters.get(0), feedClusters.get(0), softAssert); softAssert.assertAll(); } private void openProperties() { final WebElement heading = propertiesBlock.findElement(By.tagName("h4")); assertEquals(heading.getText(), "Properties", "Unexpected heading of properties box."); final WebElement upButton = propertiesBlock.findElement(By.className("pointer")); upButton.click(); } private void checkFeedCluster(WebElement cluster, Cluster feedCluster, SoftAssert softAssert) { final List<WebElement> clusterElements = cluster.findElements(By.xpath("./div")); final String vClusterName = clusterElements.get(1).getText(); softAssert.assertNotNull(feedCluster, "Unexpected feed cluster is displayed: " + vClusterName); final String clusterType = clusterElements.get(0).getText(); softAssert.assertEquals(clusterType, WordUtils.capitalize(feedCluster.getType().toString().toLowerCase() + " Cluster"), "Unexpected cluster type for cluster: " + vClusterName); softAssert.assertEquals(clusterElements.get(2).getText(), "Start: " + feedCluster.getValidity().getStart() + "\nEnd: " + feedCluster.getValidity().getEnd(), "Unexpected validity of the cluster: " + vClusterName); softAssert.assertEquals(clusterElements.get(3).getText(), "Timezone: UTC", "Unexpected timezone for validity of the cluster: " + vClusterName); softAssert.assertEquals(clusterElements.get(4).getText(), "Retention: Archive in " + feedCluster.getRetention().getLimit().getFrequency() + " " + feedCluster.getRetention().getLimit().getTimeUnit(), "Unexpected retention associated with cluster: " + vClusterName); } private List<String> getFeedPropString(FeedMerlin feed) { List<String> retVals = new ArrayList<>(); for (Property property : feed.getProperties().getProperties()) { retVals.add(property.getName() + ": " + property.getValue()); } Collections.sort(retVals); return retVals; } public void checkProcessProperties(ProcessMerlin process) { openProperties(); final WebElement propertiesBox = propertiesBlock.findElement(By.xpath("//div[@ui-view='processSummary']")); UIAssert.assertDisplayed(propertiesBox, "Properties box"); final List<WebElement> propertiesParts = propertiesBox.findElements(By.xpath("./div")); final WebElement generalPropBlock = propertiesParts.get(0); final WebElement clusterPropBlock = propertiesParts.get(1); final WebElement inputPropBlock = propertiesParts.get(2); final WebElement outputPropBlock = propertiesParts.get(3); //checking general properties final List<WebElement> generalPropParts = generalPropBlock.findElement(By.xpath("./*")).findElements(By.xpath("./*")); SoftAssert softAssert = new SoftAssert(); softAssert.assertEquals(generalPropParts.get(0).getText(), "Process", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(1).getText(), "Name", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(2).getText(), process.getName(), "Unexpected process name in general properties."); softAssert.assertEquals(generalPropParts.get(3).getText(), "Tags", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(4).getText(), StringUtils.defaultIfBlank(process.getTags(), "No tags selected"), "Unexpected tags in general properties."); softAssert.assertEquals(generalPropParts.get(5).getText(), "Workflow", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(6).getText(), "Name\nEngine\nVersion", "Unexpected workflow properties in general properties."); softAssert.assertEquals(generalPropParts.get(7).getText(), String.format("%s%n%s%n%s", StringUtils.defaultIfBlank(process.getWorkflow().getName(), ""), process.getWorkflow().getEngine(), process.getWorkflow().getVersion()), "Unexpected workflow properties in general properties."); softAssert.assertEquals(generalPropParts.get(7).getText(), "Path", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(8).getText(), process.getWorkflow().getPath(), "Unexpected workflow path in general properties."); softAssert.assertEquals(generalPropParts.get(9).getText(), "Timing", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(10).getText(), "Timezone", "Unexpected label in general properties."); softAssert.assertEquals(generalPropParts.get(12).getText(), String.format("Frequency%nEvery %s %s%n", process.getFrequency().getFrequency(), process.getFrequency().getTimeUnit()) + "Max. parallel instances\n" + process.getParallel() + "\nOrder\n" + process.getOrder().toString(), "Unexpected frequency/parallel/order info in general properties."); softAssert.assertEquals(generalPropParts.get(13).getText(), "Retry", "Unexpected label in general properties."); final Retry processRetry = process.getRetry(); softAssert.assertEquals(generalPropParts.get(14).getText(), "Policy\n" + processRetry.getPolicy().toString().toLowerCase() + "\nAttempts\n" + processRetry.getAttempts() + "\nDelay\nUp to " + processRetry.getDelay().getFrequency() + " " + processRetry.getDelay().getTimeUnit(), "Unexpected policy/attempt/delay in general properties."); //checking cluster properties final List<WebElement> allClusterProps = clusterPropBlock.findElements(By.xpath("./div/div/div")); final WebElement clustersHeading = clusterPropBlock.findElement(By.xpath(".//h5")); softAssert.assertEquals(clustersHeading.getText(), "Clusters", "Unexpected label in clusters heading"); for (WebElement oneClusterProp : allClusterProps) { final List<WebElement> clusterPropParts = oneClusterProp.findElements(By.xpath("./*")); softAssert.assertEquals(clusterPropParts.get(0).getText(), "Name", "Unexpected label in clusters properties"); final String clusterName = clusterPropParts.get(1).getText(); final org.apache.falcon.entity.v0.process.Cluster processCluster = process.getClusterByName(clusterName); softAssert.assertNotNull(processCluster, "cluster with name " + clusterName + " was not present in process."); softAssert.assertEquals(clusterName, processCluster.getName(), "Unexpected cluster name in clusters properties"); softAssert.assertEquals(clusterPropParts.get(2).getText(), "Validity", "Unexpected label in clusters properties"); softAssert.assertEquals(clusterPropParts.get(3).getText(), "Start\n" + processCluster.getValidity().getStart() + "\nEnd\n" + processCluster.getValidity().getEnd(), "Unexpected start/end time in clusters properties"); } //checking inputs properties final WebElement inputHeading = inputPropBlock.findElement(By.xpath(".//h5")); softAssert.assertEquals(inputHeading.getText(), "Inputs", "Unexpected heading for input properties."); final List<WebElement> allInputsProps = inputPropBlock.findElements(By.xpath("./div/div/*")); for (WebElement oneInputProps : allInputsProps) { final List<WebElement> inputPropParts = oneInputProps.findElements(By.xpath("./*")); softAssert.assertEquals(inputPropParts.get(0).getText(), "Name", "Unexpected label in input properties"); final String inputName = inputPropParts.get(1).getText(); final Input processInput = process.getInputByName(inputName); softAssert.assertEquals(inputName, processInput.getName(), "Unexpected input name in input properties"); softAssert.assertEquals(inputPropParts.get(2).getText(), "Feed", "Unexpected label in input properties"); softAssert.assertEquals(inputPropParts.get(3).getText(), processInput.getFeed(), "Unexpected label in input properties"); softAssert.assertEquals(inputPropParts.get(4).getText(), "Instance", "Unexpected label in input properties"); softAssert.assertEquals(inputPropParts.get(5).getText(), "Start\n" + processInput.getStart() + "\nEnd\n" + processInput.getEnd(), "Unexpected start/end in input properties"); } final WebElement outputHeading = outputPropBlock.findElement(By.tagName("h5")); softAssert.assertEquals(outputHeading.getText(), "Outputs", "Unexpected label for output properties."); final List<WebElement> allOutputsProps = outputPropBlock.findElements(By.xpath("./div/div/*")); for (WebElement oneOutputProps : allOutputsProps) { final List<WebElement> outputPropParts = oneOutputProps.findElements(By.xpath("./*")); softAssert.assertEquals(outputPropParts.get(0).getText(), "Name", "Unexpected label in output properties"); final String outputName = outputPropParts.get(1).getText(); final Output processOutput = process.getOutputByName(outputName); softAssert.assertEquals(outputName, processOutput.getName(), "Unexpected output name in output properties"); softAssert.assertEquals(outputPropParts.get(2).getText(), "Feed", "Unexpected label in output properties"); softAssert.assertEquals(outputPropParts.get(3).getText(), processOutput.getFeed(), "Unexpected feed name in output properties"); softAssert.assertEquals(outputPropParts.get(4).getText(), "Instance", "Unexpected label in output properties"); softAssert.assertEquals(outputPropParts.get(5).getText(), processOutput.getInstance(), "Unexpected instance in output properties"); softAssert.assertAll(); } } public void performActionOnSelectedInstances(InstanceAction instanceAction) { driver.findElement(By.xpath(String.format("//td/div[%d]", instanceAction.ordinal() + 1))).click(); waitForAngularToFinish(); //timeout to refresh a view TimeUtil.sleepSeconds(2); } public InstanceSummary getInstanceSummary() { return new InstanceSummary(this); } /** * Class representing all the displayed instance. */ public static class InstanceSummary { private final WebElement instanceListBox; private final WebElement summaryTableHeading; public InstanceSummary(EntityPage entityPage) { instanceListBox = entityPage.instanceListBox; UIAssert.assertDisplayed(instanceListBox, "instance list box"); assertEquals(instanceListBox.findElement(By.tagName("h4")).getText(), "Instances", "Unexpected heading in instances box."); summaryTableHeading = instanceListBox.findElement(By.xpath(".//thead/tr")); } private List<WebElement> getTableRows() { return instanceListBox.findElements(By.xpath(".//tbody/tr")); } /** * Get instance summary starting for all the pages. * @return instance summary */ public List<OneInstanceSummary> getSummary() { List<OneInstanceSummary> summary = new ArrayList<>(); final List<WebElement> tableBody = getTableRows(); //last line has page number final WebElement pageNumberRow = tableBody.remove(tableBody.size() - 1); final List<WebElement> pages = pageNumberRow.findElement(By.className("pagination")) .findElements(By.className("ng-scope")); final int numberOfPages = pages.size(); for (int pageNumber = 1; pageNumber <= numberOfPages; ++pageNumber) { //We want to use new web elements to avoid stale element issues final List<WebElement> newTableBody = getTableRows(); //last line has page number final WebElement newPageNumberRow = newTableBody.remove(newTableBody.size() - 1); final List<WebElement> newPages = newPageNumberRow.findElement(By.className("pagination")) .findElements(By.className("ng-scope")); newPages.get(pageNumber-1).findElement(By.tagName("a")).click(); summary.addAll(getSummaryInner()); } return summary; } /** * Get instance summary starting for the current page. * @return instance summary */ private List<OneInstanceSummary> getSummaryInner() { List<OneInstanceSummary> summary = new ArrayList<>(); final List<WebElement> tableBody = getTableRows(); //first line in body has buttons tableBody.remove(0); //last line has page number tableBody.remove(tableBody.size() - 1); //second last line is horizontal line tableBody.remove(tableBody.size() - 1); if (tableBody.size() == 1 && tableBody.get(0).getText().equals("There are no results")) { return summary; } for (WebElement oneSummaryRow : tableBody) { summary.add(new OneInstanceSummary(oneSummaryRow)); } return summary; } public void check() { final List<WebElement> summaryHeadParts = getSummaryHeadParts(); getSelectAllCheckBox(summaryHeadParts); final WebElement instanceHeadLabel = summaryHeadParts.get(1); assertEquals(instanceHeadLabel.getText(), "Instance", "Unexpected label in instance summary heading"); getSummaryStartedButton(); getSummaryEndedButton(); getStatusDropDown(); } public void setInstanceSummaryStartTime(String timeStr) { final WebElement startTimeButton = getSummaryStartedButton(); startTimeButton.clear(); sendKeysSlowly(startTimeButton, timeStr); startTimeButton.sendKeys(Keys.ENTER); } public void setInstanceSummaryEndTime(String timeStr) { final WebElement endTimeButton = getSummaryEndedButton(); endTimeButton.clear(); sendKeysSlowly(endTimeButton, timeStr); endTimeButton.sendKeys(Keys.ENTER); } public void selectInstanceSummaryStatus(String labelText) { getStatusDropDown().selectByVisibleText(labelText); } public static OneInstanceSummary getOneSummary(final List<OneInstanceSummary> summaries, final String nominalTime) { for (OneInstanceSummary oneSummary : summaries) { if (oneSummary.getNominalTime().equals(nominalTime)) { return oneSummary; } } return null; } public void checkSummary(InstancesResult.Instance[] apiSummary) { final List<OneInstanceSummary> summary = getSummary(); assertEquals(apiSummary.length, summary.size(), String.format("Length of the displayed instance summary is not same: %s %s", Arrays.toString(apiSummary), summary)); for (InstancesResult.Instance oneApiSummary : apiSummary) { final OneInstanceSummary oneSummary = getOneSummary(summary, oneApiSummary.instance); assertEquals(oneApiSummary.instance, oneSummary.getNominalTime(), "Nominal time of instance summary doesn't match."); final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); final Date apiStartTime = oneApiSummary.getStartTime(); if (apiStartTime == null) { assertTrue(StringUtils.isEmpty(oneSummary.getStartTime()), "Displayed start time : " + oneSummary + " is not " + "consistent with start time of api which is null"); } else { assertEquals(oneSummary.getStartTime(), dateFormat.format(apiStartTime), "Displayed start time : " + oneSummary + " is not " + "consistent with start time of api: " + apiStartTime); } final Date apiEndTime = oneApiSummary.getEndTime(); if (apiEndTime == null) { assertTrue(StringUtils.isEmpty(oneSummary.getEndTime()), "Displayed end time : " + oneSummary + " is not " + "consistent end start time of api which is null"); } else { assertEquals(oneSummary.getEndTime(), dateFormat.format(apiEndTime), "Displayed end time : " + oneSummary + " is not " + "consistent with end time of api: " + apiEndTime); } assertEquals(oneApiSummary.status.toString(), oneSummary.getStatus(), "Status of instance summary doesn't match."); } } public WebElement getSummaryStartedButton() { final WebElement startedBox = getSummaryHeadParts().get(2); assertEquals(startedBox.getText(), "Started ", "Unexpected label in instance summary heading"); return startedBox.findElement(By.tagName("input")); } public WebElement getSummaryEndedButton() { final WebElement endedBox = getSummaryHeadParts().get(3); assertEquals(endedBox.getText(), "Ended ", "Unexpected label in instance summary heading"); return endedBox.findElement(By.tagName("input")); } public Select getStatusDropDown() { final WebElement statusBox = getSummaryHeadParts().get(4); assertEquals(statusBox.getText(), "Status \nALL\nRUNNING\nSUCCEEDED\nSUSPENDED\nWAITING\nKILLED", "Unexpected label in instance summary heading"); return new Select(statusBox.findElement(By.tagName("select"))); } public List<WebElement> getSummaryHeadParts() { return summaryTableHeading.findElements(By.xpath("./th/div")); } public WebElement getSelectAllCheckBox(List<WebElement> summaryHeadParts) { return summaryHeadParts.get(0).findElement(By.tagName("input")); } } public InstancePage openInstance(String nominalTime) { instanceListBox.findElement(By.xpath("//button[contains(.,'" + nominalTime + "')]")).click(); return PageFactory.initElements(driver, InstancePage.class); } /** * Class representing summary of one instance. */ public static final class OneInstanceSummary { private final WebElement oneInstanceSummary; private final String startTime; private final String endTime; private final String status; private final String nominalTime; private final Map<Object, Object> statusColorMap = ImmutableMap.builder() .put("WAITING", "rgba(51, 51, 51, 1)") .put("RUNNING", "") .put("KILLED", "") .put("SUCCEEDED", "") .put("SUSPENDED", "") .put("FAILED", "").build(); private boolean isCheckBoxTicked; private OneInstanceSummary(WebElement oneInstanceSummary) { this.oneInstanceSummary = oneInstanceSummary; nominalTime = getNominalTimeButton().getText(); startTime = getSummaryCols().get(2).getText(); endTime = getSummaryCols().get(3).getText(); final WebElement statusElement = getSummaryCols().get(4); assertTrue(statusElement.isDisplayed(), "Status should be displayed"); final String statusText = statusElement.getText(); final Object expectedColor = statusColorMap.get(statusText.trim()); assertNotNull(expectedColor, "Unexpected status: " + statusText + " not found in: " + statusColorMap); //status color not checked //final String actualColor = statusElement.getCssValue("color"); //assertEquals(actualColor, expectedColor, // "Unexpected color for status in process instances block: " + statusText); status = statusText; isCheckBoxTicked = getCheckBox().isSelected(); } private List<WebElement> getSummaryCols() { return oneInstanceSummary.findElements(By.tagName("td")); } private WebElement getCheckBox() { return getSummaryCols().get(0).findElement(By.tagName("input")); } private WebElement getNominalTimeButton() { return getSummaryCols().get(1); } public String getStartTime() { return startTime; } public String getEndTime() { return endTime; } public String getStatus() { return status; } public String getNominalTime() { return nominalTime; } public boolean isCheckBoxSelected() { return isCheckBoxTicked; } /** * Click the checkbox corresponding to this result. It is the responsibility of the * client to make sure that the web element for the instance is displayed and valid. */ public void clickCheckBox() { getCheckBox().click(); // Toggling of checkbox should change its internal state // Note that we can't expect the web element to be displayed & valid at the point this // object is used isCheckBoxTicked = !isCheckBoxTicked; } @Override public String toString() { return "OneInstanceSummary{" + "checkBox=" + isCheckBoxSelected() + ", nominalTime=" + getNominalTime() + ", startTime=" + getStartTime() + ", endTime=" + getEndTime() + ", status=" + getStatus() + "}"; } } }