/* * Copyright 2015-2017 Hewlett Packard Enterprise Development Company, L.P. * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. */ package com.autonomy.abc.bi; import com.autonomy.abc.base.IdolFindTestBase; import com.autonomy.abc.base.Role; import com.autonomy.abc.selenium.find.FindService; import com.autonomy.abc.selenium.find.IdolFindPage; import com.autonomy.abc.selenium.find.application.BIIdolFind; import com.autonomy.abc.selenium.find.application.BIIdolFindElementFactory; import com.autonomy.abc.selenium.find.application.UserRole; import com.autonomy.abc.selenium.find.filters.DateOption; import com.autonomy.abc.selenium.find.filters.GraphFilterContainer; import com.autonomy.abc.selenium.find.filters.IdolFilterPanel; import com.autonomy.abc.selenium.find.numericWidgets.MainNumericWidget; import com.autonomy.abc.selenium.find.numericWidgets.NumericWidget; import com.autonomy.abc.selenium.find.numericWidgets.NumericWidgetService; import com.autonomy.abc.selenium.find.results.ListView; import com.autonomy.abc.selenium.find.save.SavedSearchPanel; import com.autonomy.abc.selenium.find.save.SavedSearchService; import com.autonomy.abc.selenium.find.save.SearchTabBar; import com.autonomy.abc.selenium.find.save.SearchType; import com.autonomy.abc.selenium.query.IndexFilter; import com.hp.autonomy.frontend.selenium.config.Browser; import com.hp.autonomy.frontend.selenium.config.TestConfig; import com.hp.autonomy.frontend.selenium.element.DatePicker; import com.hp.autonomy.frontend.selenium.framework.logging.ActiveBug; import com.hp.autonomy.frontend.selenium.framework.logging.ResolvedBug; import com.hp.autonomy.frontend.selenium.util.DriverUtil; import com.hp.autonomy.frontend.selenium.util.Waits; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import static com.hp.autonomy.frontend.selenium.framework.state.TestStateAssert.verifyThat; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.core.Is.is; import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase; //NB: FIND-399 -> these tests will stop needing to re-assign MainGraph every minute once stops reloading @Role(UserRole.BIFHI) public class NumericWidgetITCase extends IdolFindTestBase { private FindService findService; private IdolFindPage findPage; private NumericWidgetService numericService; public NumericWidgetITCase(final TestConfig config) { super(config); } @Override public BIIdolFindElementFactory getElementFactory() { return (BIIdolFindElementFactory)super.getElementFactory(); } @Before public void setUp() { findPage = getElementFactory().getFindPage(); findService = getApplication().findService(); numericService = ((BIIdolFind)getApplication()).numericWidgetService(); } /*##########ANY NUMERIC GRAPH###########*/ @Test public void testClickingOnFilterPanelGraphOpensMain() { findService.searchAnyView("book"); filters().waitForParametricFields(); assertThat("Default: main graph not shown", !findPage.mainGraphDisplayed()); MainNumericWidget mainGraph; for(final GraphFilterContainer container : filters().graphContainers()) { final String graphTitle = numericService.selectFilterGraph(container, getDriver()); verifyThat("Main graph now shown", findPage.mainGraphDisplayed()); mainGraph = findPage.mainGraph(); verifyThat("Correct graph is open", mainGraph.header(), equalToIgnoringCase(graphTitle)); } findPage.mainGraph().closeWidget(); verifyThat("Main graph now gone", !findPage.mainGraphDisplayed()); } @Test @ResolvedBug("FIND-356") public void testSelectionRecDoesNotDisappear() { MainNumericWidget mainGraph = numericService.searchAndSelectNthGraph(0, "politics", getDriver()); DriverUtil.clickAndDrag(100, mainGraph.graph(), getDriver()); filters().waitForParametricFields(); mainGraph.waitUntilWidgetLoaded(); mainGraph = findPage.mainGraph(); mainGraph.waitUntilRectangleBack(); verifyThat("Selection rectangle hasn't disappeared", mainGraph.graphAsWidget().selectionRectangleExists()); } @Test public void testSelectionRecFiltersResults() { MainNumericWidget mainGraph = numericService.searchAndSelectNthGraph(0, "space", getDriver()); final ListView results = findPage.goToListView(); results.waitForResultsToLoad(); final int beforeNumberResults = results.getTotalResultsNum(); mainGraph.waitUntilWidgetLoaded(); final String beforeMin = mainGraph.minFieldValue(); final String beforeMax = mainGraph.maxFieldValue(); mainGraph.selectHalfTheBars(); mainGraph = numericService.waitForReload(); verifyThat("Filter label has appeared", findPage.filterLabelsText(), hasSize(1)); verifyThat("Fewer results", results.getTotalResultsNum(), lessThan(beforeNumberResults)); verifyThat("Min field text value changed", mainGraph.minFieldValue(), not(is(beforeMin))); verifyThat("Max field text value changed", mainGraph.maxFieldValue(), not(is(beforeMax))); NumericWidget sidePanelChart = filters().getNamedGraph("autn date").getChart(); verifyThat("Side panel chart has selection rectangle", sidePanelChart.selectionRectangleExists()); mainGraph.reset(); mainGraph = numericService.waitForReload(); verifyThat("Selection rectangle gone from centre", !mainGraph.graphAsWidget().selectionRectangleExists()); verifyThat("Min bound returned to original", mainGraph.minFieldValue(), is(beforeMin)); verifyThat("Max bound returned to original", mainGraph.maxFieldValue(), is(beforeMax)); sidePanelChart = filters().getNamedGraph("autn date").getChart(); verifyThat("Selection rectangle gone from side panel", !sidePanelChart.selectionRectangleExists()); } @Test @ActiveBug("FIND-392") public void testWidgetsReflectCurrentSearch() { final MainNumericWidget mainGraph = numericService.searchAndSelectNthGraph(2, "face", getDriver()); mainGraph.selectFractionOfBars(3, 4); numericService.waitForReload(); verifyThat("There are results present", findPage.goToListView().getTotalResultsNum(), greaterThan(0)); } @Test @ResolvedBug("FIND-366") public void testFilterLabelsUpdate() { findService.searchAnyView("dance"); filters().waitForParametricFields(); numericService.selectFilterGraph(filters().getNthGraph(0), getDriver()); final MainNumericWidget mainGraph = findPage.mainGraph(); DriverUtil.clickAndDrag(100, mainGraph.graph(), getDriver()); final String label = findPage.filterLabelsText().get(0); DriverUtil.clickAndDrag(-100, mainGraph.graph(), getDriver()); final String changedLabel = findPage.filterLabelsText().get(0); assertThat("The label has changed", changedLabel, not(is(label))); } @Test @ResolvedBug("FIND-282") @ActiveBug("FIND-417") public void testFilterLabelsHaveTitleOnTooltip() { findService.searchAnyView("ball"); filters().waitForParametricFields(); final List<String> graphTitles = filterByAllGraphs(); final List<WebElement> webElements = findPage.filterLabels(); verifyThat("All filters have a label", webElements, hasSize(graphTitles.size())); final List<String> tooltipsText = webElements.stream() .map(labelElement -> labelElement.findElement(By.cssSelector(".filter-display-text")).getAttribute("data-original-title")) .collect(Collectors.toList()); for(int i = 0; i < graphTitles.size(); i++) { final String title = graphTitles.get(i); verifyThat("Title " + title.toLowerCase() + " is in filter tooltip", tooltipsText.get(i).toLowerCase(), containsString(title.toLowerCase())); } } private List<String> filterByAllGraphs() { final List<String> titles = new ArrayList<>(); for(final GraphFilterContainer container : filters().graphContainers()) { //TODO: this is reloading which is making things stale titles.add(numericService.selectFilterGraph(container, getDriver())); DriverUtil.clickAndDrag(100, findPage.mainGraph().graph(), getDriver()); } return titles; } @Test @ResolvedBug("FIND-273") public void testRemovingViaFilterLabelRemovesSelection() { MainNumericWidget mainGraph = numericService.searchAndSelectFirstNumericGraph("space", getDriver()); DriverUtil.clickAndDrag(100, mainGraph.graph(), getDriver()); filters().waitForParametricFields(); mainGraph = findPage.mainGraph(); mainGraph.waitUntilRectangleBack(); final List<WebElement> labels = findPage.filterLabels(); assertThat("Filter label appeared", labels, hasSize(1)); findPage.removeFilterLabel(labels.get(0)); filters().waitForParametricFields(); final NumericWidget sidePanelChart = filters().getFirstNumericGraph().getChart(); verifyThat("Side panel chart selection rectangle gone", !sidePanelChart.selectionRectangleExists()); } @Test @ResolvedBug({"FIND-270", "FIND-143"}) public void testFilterLabelPresentInSavedQuery() { final String searchName = "meh"; final MainNumericWidget mainGraph = numericService.searchAndSelectNthGraph(1, "moon", getDriver()); DriverUtil.clickAndDrag(-50, mainGraph.graph(), getDriver()); final SavedSearchService saveService = getApplication().savedSearchService(); final SearchTabBar searchTabs = getElementFactory().getSearchTabBar(); try { saveService.saveCurrentAs(searchName, SearchType.QUERY); saveService.openNewTab(); searchTabs.switchTo(searchName); Waits.loadOrFadeWait(); verifyThat("Filter labels have appeared", findPage.filterLabels(), not(empty())); } finally { findService.searchAnyView("back to results"); saveService.deleteAll(); } } /*##########DATE GRAPHS##########*/ @Test @ResolvedBug("FIND-390") public void testInteractionWithRegularDateFilters() { final MainNumericWidget mainGraph = numericService.searchAndSelectFirstDateGraph("whatever", getDriver()); filters().toggleFilter(DateOption.MONTH); filters().waitForParametricFields(); mainGraph.waitUntilWidgetLoaded(); final WebElement errorMessage = mainGraph.errorMessage(); verifyThat("Error message not displayed", !errorMessage.isDisplayed()); verifyThat("Error message not 'failed to load data'", errorMessage.getText(), not(equalToIgnoringCase("Failed to load data"))); } @Test @ResolvedBug("FIND-400") @Ignore("Numeric widget reloading currently makes it impossible to Selenium test this.") public void testInputDateBoundsAsText() { MainNumericWidget mainGraph = numericService.searchAndSelectFirstDateGraph("red", getDriver()); final String startDate = "1976-10-22 08:46"; final String endDate = "2012-10-10 21:49"; LOGGER.info("Currently fails due to reloading of numeric widget"); mainGraph = setMinAndMax(startDate, endDate, mainGraph); mainGraph.waitUntilWidgetLoaded(); dateRectangleHover(mainGraph, "1976", "2012"); } @Test @ResolvedBug("FIND-633") @ActiveBug("FIND-690") //TODO: make less data-dependent -> can't guarantee what years are going to be there public void testInputDateBoundsWithCalendar() { MainNumericWidget mainGraph = numericService.searchAndSelectFirstDateGraph("tragedy", getDriver()); final DatePicker startCalendar = mainGraph.openCalendar(mainGraph.startCalendar()); assertThat("Calendar widget has opened", mainGraph.calendarHasOpened()); startCalendar.calendarDateSelect(new Date(76, 8, 26)); final DatePicker endCalendar = mainGraph.openCalendar(mainGraph.endCalendar()); endCalendar.calendarDateSelect(new Date(120, 3, 22)); mainGraph = findPage.mainGraph(); mainGraph.waitUntilWidgetLoaded(); mainGraph.waitUntilRectangleBack(); //to close the calendar pop-up mainGraph.messageRow().click(); mainGraph.waitUntilDatePickerGone(); dateRectangleHover(mainGraph, "1976", "2022"); } private void dateRectangleHover(final MainNumericWidget mainGraph, final String start, final String end) { mainGraph.rectangleHoverRight(); final String rightCorner = mainGraph.hoverMessage().split(" ")[0]; mainGraph.rectangleHoverLeft(); final String leftCorner = mainGraph.hoverMessage().split(" ")[0]; verifyThat("Start bound is correct", leftCorner, containsString(start)); verifyThat("End bound is not an empty string due to selection rectangle truncation", leftCorner, not("")); verifyThat("End bound is correct", rightCorner, containsString(end)); } @Test @ResolvedBug({"FIND-389", "FIND-143"}) public void testSnapshotDateRangesDisplayedCorrectly() { final MainNumericWidget mainGraph = numericService.searchAndSelectFirstDateGraph("dire", getDriver()); final String filterType = mainGraph.header(); DriverUtil.clickAndDrag(-50, mainGraph.graph(), getDriver()); findPage.waitForParametricValuesToLoad(); final SavedSearchService saveService = getApplication().savedSearchService(); final SearchTabBar searchTabs = getElementFactory().getSearchTabBar(); try { saveService.saveCurrentAs("bad", SearchType.SNAPSHOT); searchTabs.switchTo("bad"); Waits.loadOrFadeWait(); final String dateRange = new SavedSearchPanel(getDriver()).getFirstSelectedFilterOfType(filterType); verifyThat("Date range formatted like date", dateRange, allOf(containsString("/"), containsString(":"))); } finally { searchTabs.switchTo("bad"); saveService.deleteCurrentSearch(); } } /*##########NON-DATE GRAPHS##########*/ @Test @ResolvedBug("FIND-365") public void testFilterLabelFormatReflectsNumericData() { final MainNumericWidget mainGraph = numericService.searchAndSelectFirstNumericGraph("beer", getDriver()); DriverUtil.clickAndDrag(200, mainGraph.graph(), getDriver()); numericService.waitForReload(); verifyThat("Filter label doesn't have time format", findPage.filterLabelsText().get(0), not(containsString(":"))); } @Test @ActiveBug(value = "FIND-768", browsers = Browser.IE) public void testInputNumericBoundsAsText() { MainNumericWidget mainGraph = numericService.searchAndSelectFirstNumericGraph("red", getDriver()); final double fractionToSelect = 3.0; final double selectRange = mainGraph.getRange() / fractionToSelect; final String minValue = mainGraph.minFieldValue(); final String maxValue = Double.toString(Double.parseDouble(minValue) + selectRange); final int rangeMinusDelta = (int)(selectRange * 0.98); final int rangePlusDelta = (int)(selectRange * 1.02); final int numericUnitsPerChartWidth = (int)mainGraph.getRange() / mainGraph.graphWidth(); //#1 testing that correct proportion of chart selected mainGraph = setMinAndMax(minValue, maxValue, mainGraph); Waits.loadOrFadeWait(); final int newUnitsPerWidthUnit = 250 / findPage.mainGraph().graphAsWidget().selectionRectangleWidth(); verifyThat("Selection rectangle covering correct fraction of chart", newUnitsPerWidthUnit, is(numericUnitsPerChartWidth)); //#2 testing correct boundaries of rectangle mainGraph.waitUntilWidgetLoaded(); mainGraph = findPage.mainGraph(); mainGraph.rectangleHoverRight(); final String rightCorner = mainGraph.hoverMessage(); mainGraph.rectangleHoverLeft(); final String leftCorner = mainGraph.hoverMessage(); final int rectangleRange = (int)(Double.parseDouble(rightCorner) - Double.parseDouble(leftCorner)); verifyThat("Edges of rectangle reflect bounds correctly", rectangleRange, allOf(greaterThanOrEqualTo(rangeMinusDelta), lessThanOrEqualTo(rangePlusDelta))); } @Test @ResolvedBug("FIND-393") public void testTextMaxBoundCannotBeLessThanMin() { final String lowNum = "0"; final String highNum = "600"; MainNumericWidget mainGraph = numericService.searchAndSelectFirstNumericGraph("red", getDriver()); mainGraph = setMinAndMax(highNum, lowNum, mainGraph); verifyThat("Min bound re-set to value of max", mainGraph.minFieldValue(), is(lowNum)); mainGraph.setMaxValueViaText(lowNum); Waits.loadOrFadeWait(); mainGraph = findPage.mainGraph(); mainGraph.setMinValueViaText(highNum); verifyThat("Max bound re-set to value of min", mainGraph.maxFieldValue(), is(highNum)); } private MainNumericWidget setMinAndMax(final String min, final String max, MainNumericWidget mainGraph) { Waits.loadOrFadeWait(); Waits.loadOrFadeWait(); mainGraph.setMinValueViaText(min); //bad but soon the graph will not reload so this won't be necessary Waits.loadOrFadeWait(); Waits.loadOrFadeWait(); mainGraph = findPage.mainGraph(); mainGraph.setMaxValueViaText(max); return findPage.mainGraph(); } //###########BOTH DATE AND NUMERIC NEEDED###########// @Test @Ignore("Desired behaviour but not implemented and not a bug") public void testMinAndMaxReflectCurrentSearch() { //currently 0th graph is place elevation (i.e. non-date) numericService.searchAndSelectFirstNumericGraph("*", getDriver()); checkBoundsForPlaceElevationWidget(); numericService.searchAndSelectFirstDateGraph("*", getDriver()); checkBoundsForDateWidget(); } private void checkBoundsForPlaceElevationWidget() { findPage.filterBy(new IndexFilter("Cities")); MainNumericWidget mainGraph = findPage.mainGraph(); final int originalRange = (int)mainGraph.setAndGetFullRange(); findService.searchAnyView("Tse"); mainGraph = findPage.mainGraph(); final int newRange = (int)mainGraph.setAndGetFullRange(); verifyThat("Bounds are determined by current query for non-date widget", newRange, lessThan(originalRange)); mainGraph.reset(); } private void checkBoundsForDateWidget() { final List<Date> oldD = findPage.mainGraph().getDates(); findPage.filterBy(IndexFilter.ALL); findService.searchAnyView("George Orwell"); final List<Date> newD = findPage.mainGraph().getDates(); if(newD.get(0).after(oldD.get(0))) { verifyThat("Bounds are determined by current query for date widget", newD.get(0).after(oldD.get(0))); } else { verifyThat("Bounds are determined by current query for date widget", newD.get(1).before(oldD.get(1))); } } private IdolFilterPanel filters() { return getElementFactory().getFilterPanel(); } }