/*
 * 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.geode.tools.pulse.tests.ui;

import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.assertMemberSortingByCpuUsage;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.assertMemberSortingByHeapUsage;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.assertMemberSortingByRzHeapUsage;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.assertMemberSortingBySgCpuUsage;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.assertMemberSortingBySgHeapUsage;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.assertMemeberSortingByRzCpuUsage;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.clickElementUsingId;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.clickElementUsingXpath;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.findElementByXpath;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.getPersistanceEnabled;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.getPropertyValue;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.getRegionsFromDataBrowser;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.getTextUsingId;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.getTextUsingXpath;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.mouseClickAndHoldOverElementById;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.mouseReleaseById;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToDataPrespectiveGridView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToRedundancyZonesGridView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToRedundancyZonesTreeView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToRegionDetailsGridView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToRegionDetailsView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToServerGroupGridView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToServerGroupTreeView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToTopologyGridView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.navigateToTopologyTreeView;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.sendKeysUsingId;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.validateDataPrespectiveGridData;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.validateRedundancyZonesGridData;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.validateRegionDetailsGridData;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.validateServerGroupGridData;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.validateTopologyGridData;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.verifyElementAttributeById;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.verifyElementPresentById;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.verifyElementPresentByLinkText;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.verifyElementPresentByXpath;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.verifyTextPresrntById;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.verifyTextPresrntByXpath;
import static org.apache.geode.tools.pulse.tests.ui.PulseTestUtils.waitForElementWithId;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import org.apache.geode.tools.pulse.tests.DataBrowserResultLoader;
import org.apache.geode.tools.pulse.tests.PulseTestData;
import org.apache.geode.tools.pulse.tests.PulseTestLocators;
import org.apache.geode.tools.pulse.tests.rules.ScreenshotOnFailureRule;
import org.apache.geode.tools.pulse.tests.rules.ServerRule;
import org.apache.geode.tools.pulse.tests.rules.WebDriverRule;

/**
 * This test class contains automated tests for Pulse application related to 1. Different grid data
 * validations for example - Topology, Server Group, Redundancy Zone 2. Data Browser 3.
 *
 * @since GemFire 2014-04-02
 */
public class PulseAutomatedTest extends PulseBase {

  @ClassRule
  public static ServerRule serverRule = new ServerRule("pulse-auth.json");

  @Rule
  public WebDriverRule webDriverRule =
      new WebDriverRule("pulseUser", "12345", serverRule.getPulseURL());

  @Rule
  public ScreenshotOnFailureRule screenshotOnFailureRule =
      new ScreenshotOnFailureRule(this::getWebDriver);

  @Override
  public WebDriver getWebDriver() {
    return webDriverRule.getDriver();
  }

  @Override
  public String getPulseURL() {
    return serverRule.getPulseURL();
  }

  @Before
  public void setupPulseTestUtils() {
    PulseTestUtils.setDriverProvider(() -> webDriverRule.getDriver());
    getWebDriver().get(getPulseURL() + "clusterDetail.html");
  }

  @Test
  public void serverGroupGridDataValidation() {
    navigateToServerGroupGridView();
    validateServerGroupGridData();
  }

  @Test
  public void redundancyZonesGridDataValidation() {
    navigateToRedundancyZonesGridView();
    validateRedundancyZonesGridData();
  }

  @Test
  public void topologyGridDataValidation() {
    navigateToTopologyGridView();
    validateTopologyGridData();
  }

  @Test
  public void dataViewGridDataValidation() {
    navigateToDataPrespectiveGridView();
    validateDataPrespectiveGridData();
  }

  @Test
  public void regionDetailsGridDataValidation() {
    navigateToRegionDetailsGridView();
    validateRegionDetailsGridData();

  }

  @Test
  public void regionDetailsNavigationTest() {
    navigateToRegionDetailsView();
    assertEquals("/R2", getTextUsingId(PulseTestLocators.RegionDetailsView.regionNameDivId));
  }

  @Test
  public void regionName() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.name"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionNameDivId));
  }

  @Test
  public void regionPath() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.fullPath"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionPathId));
  }

  @Test
  public void regionType() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.regionType"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionTypeId));
  }

  @Test
  public void regionMembers() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.memberCount"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionMembersTextId));
  }

  @Test
  public void regionEmptyNodes() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.emptyNodes"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionEmptyNodesId));
  }

  @Test
  public void regionEntryCount() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.systemRegionEntryCount"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionEntryCountTextId));
  }

  @Test
  public void regionDiskUsage() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.diskUsage"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionDiskUsageId));
  }

  @Test
  public void regionPersistence() {
    navigateToRegionDetailsView();
    assertEquals(getPersistanceEnabled(getPropertyValue("region.R2.persistentEnabled")),
        getTextUsingId(PulseTestLocators.RegionDetailsView.regionPersistenceId));
  }

  @Ignore("WIP")
  @Test
  public void regionMemoryUsage() {
    navigateToRegionDetailsView();
    // need to check the respective property values
  }

  @Test
  public void regionInMemoryRead() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.getsRate"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.inMemoryReadsId));

  }

  @Test
  public void regionInMemoryWrites() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.putsRate"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.inMemoryWritesId));
  }

  @Test
  public void regionDiskRead() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.diskReadsRate"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.diskReadsId));
  }

  @Test
  public void regionDiskWrites() {
    navigateToRegionDetailsView();
    assertEquals(getPropertyValue("region.R2.diskWritesRate"),
        getTextUsingId(PulseTestLocators.RegionDetailsView.diskWritesId));
  }

  @Ignore("Fails for unknown reason when run using gradle on command line")
  @Test
  public void clickHostShowsMemberTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    PulseTestUtils.waitForElementWithId(PulseTestLocators.TopologyView.nodeH1Id).click();
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM1Id);
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    PulseTestUtils.waitForElementWithId(PulseTestLocators.TopologyView.nodeH2Id).click();
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM2Id);
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    PulseTestUtils.waitForElementWithId(PulseTestLocators.TopologyView.nodeH3Id).click();
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM3Id);
  }

  @Test
  @Ignore("Issue with highlighting")
  public void verifyHostTooltipsOfTopologyGraphTest() {
    for (int i = 1; i <= 3; i++) {
      clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
      mouseClickAndHoldOverElementById("h" + i);
      verifyTextPresrntByXpath(PulseTestLocators.TopologyView.hostNameTTXpath,
          getPropertyValue("member.M" + i + ".host"));
      verifyTextPresrntByXpath(PulseTestLocators.TopologyView.cpuUsageTTXpath, "0%");
      verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memoryUsageTTXpath,
          getPropertyValue("member.M" + i + ".UsedMemory"));
      verifyTextPresrntByXpath(PulseTestLocators.TopologyView.loadAvgTTXpath,
          getPropertyValue("member.M" + i + ".loadAverage"));
      verifyTextPresrntByXpath(PulseTestLocators.TopologyView.soketsTTXpath,
          getPropertyValue("member.M" + i + ".totalFileDescriptorOpen"));
      mouseReleaseById("h" + i);
      webDriverRule.getDriver().navigate().refresh();
    }
  }

  @Ignore("Issues with member tooltip xpath")
  @Test
  public void verifyMemberTooltipsOfTopologyGraphTest() {

    verifyElementPresentById(PulseTestLocators.TopologyView.nodeH1Id);
    clickElementUsingId(PulseTestLocators.TopologyView.nodeH1Id);
    mouseClickAndHoldOverElementById(PulseTestLocators.TopologyView.memberM1Id);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memNameTTXpath,
        getPropertyValue("member.M1.member"));
    // verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memCpuUsageTTXpath,
    // getPropertyValue("member.M1.cpuUsage") + "%");
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.jvmPausesTTXpath,
        getPropertyValue("member.M1.JVMPauses"));
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.regionsTTXpath,
        getPropertyValue("member.M1.totalRegionCount"));
    verifyElementPresentById(PulseTestLocators.TopologyView.nodeH2Id);
    clickElementUsingId(PulseTestLocators.TopologyView.nodeH2Id);
    mouseClickAndHoldOverElementById(PulseTestLocators.TopologyView.memberM2Id);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memNameTTXpath,
        getPropertyValue("member.M2.member"));
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memCpuUsageTTXpath,
        getPropertyValue("member.M2.cpuUsage") + "%");
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.jvmPausesTTXpath,
        getPropertyValue("member.M2.JVMPauses"));
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.regionsTTXpath,
        getPropertyValue("member.M2.totalRegionCount"));

    verifyElementPresentById(PulseTestLocators.TopologyView.nodeH3Id);
    clickElementUsingId(PulseTestLocators.TopologyView.nodeH3Id);
    mouseClickAndHoldOverElementById(PulseTestLocators.TopologyView.memberM3Id);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memNameTTXpath,
        getPropertyValue("member.M3.member"));
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.memCpuUsageTTXpath,
        getPropertyValue("member.M3.cpuUsage") + "%");
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.jvmPausesTTXpath,
        getPropertyValue("member.M3.JVMPauses"));
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.regionsTTXpath,
        getPropertyValue("member.M3.totalRegionCount"));

  }

  @Test
  public void VerifyRGraphTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    verifyElementPresentById(PulseTestLocators.TopologyView.nodeH1Id);
    verifyElementPresentById(PulseTestLocators.TopologyView.nodeH2Id);
    verifyElementPresentById(PulseTestLocators.TopologyView.nodeH3Id);
  }

  @Test
  @Ignore("ElementNotVisible with phantomJS")
  public void clickMembersOfTopologyGraphTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.nodeH1Id);
    clickElementUsingId(PulseTestLocators.TopologyView.memberM1Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.nodeH2Id);
    clickElementUsingId(PulseTestLocators.TopologyView.memberM2Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.nodeH3Id);
    clickElementUsingId(PulseTestLocators.TopologyView.memberM3Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
  }

  @Test
  public void clickTreeMapViewShowingTreeMapTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.treeMapButtonId);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM1Id);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM2Id);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM3Id);
  }

  @Test
  public void verifyMembersPresentInTreeMapTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.treeMapButtonId);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM1Id);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM2Id);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM3Id);
    verifyTextPresrntById(PulseTestLocators.TopologyView.memberM1Id, "M1");
    verifyTextPresrntById(PulseTestLocators.TopologyView.memberM2Id, "M2");
    verifyTextPresrntById(PulseTestLocators.TopologyView.memberM3Id, "M3");
  }

  @Test
  public void clickMemberNavigatingToCorrespondingRegionTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.treeMapButtonId);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM1Id);
    verifyTextPresrntById(PulseTestLocators.TopologyView.memberM1Id, "M1");
    clickElementUsingId(PulseTestLocators.TopologyView.memberM1Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.treeMapButtonId);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM2Id);
    verifyTextPresrntById(PulseTestLocators.TopologyView.memberM2Id, "M2");
    clickElementUsingId(PulseTestLocators.TopologyView.memberM2Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.treeMapButtonId);
    verifyElementPresentById(PulseTestLocators.TopologyView.memberM3Id);
    verifyTextPresrntById(PulseTestLocators.TopologyView.memberM3Id, "M3");
    clickElementUsingId(PulseTestLocators.TopologyView.memberM3Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
  }

  @Test
  public void clickGridButtonShowsGridTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.gridButtonId);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.idM1Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.nameM1Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.hostH1Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.idM2Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.nameM2Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.hostH2Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.idM3Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.nameM3Xpath);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.hostH3Xpath);
  }

  @Test
  public void verifyMembersPresentInGridTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.gridButtonId);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.nameM1Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.nameM1Xpath, "M1");

    verifyElementPresentByXpath(PulseTestLocators.TopologyView.nameM2Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.nameM2Xpath, "M2");

    verifyElementPresentByXpath(PulseTestLocators.TopologyView.nameM3Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.nameM3Xpath, "M3");
  }

  @Test
  public void verifyHostNamesInGridTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.gridButtonId);
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.hostH1Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.hostH1Xpath, "h1");
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.hostH2Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.hostH2Xpath, "h2");
    verifyElementPresentByXpath(PulseTestLocators.TopologyView.hostH3Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.TopologyView.hostH3Xpath, "h3");
  }

  @Test
  public void clickOnGridMemNameNavigatingToCorrespondingRegionTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.gridButtonId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.nameM1Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");

    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.gridButtonId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.nameM2Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");

    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.gridButtonId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.nameM3Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
  }

  @Test
  public void verifyMembersPresentInSvrGrpTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);

    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrpsRadioXpath);
    verifyElementPresentById(PulseTestLocators.ServerGroups.serverGrp1Id);
    verifyElementPresentById(PulseTestLocators.ServerGroups.serverGrp2Id);
    verifyElementPresentById(PulseTestLocators.ServerGroups.serverGrp3Id);

    verifyElementPresentById(PulseTestLocators.ServerGroups.sg1M1Id);
    verifyElementPresentById(PulseTestLocators.ServerGroups.sg1M2Id);
    verifyElementPresentById(PulseTestLocators.ServerGroups.sg1M3Id);

    verifyElementPresentById(PulseTestLocators.ServerGroups.sg2M1Id);
    verifyElementPresentById(PulseTestLocators.ServerGroups.sg2M2Id);

    verifyElementPresentById(PulseTestLocators.ServerGroups.sg3M3Id);
  }

  @Test
  @Ignore("ElementNotVisible with phantomJS")
  public void expandAndCloseServerGroupsTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    // waitForElement(findElementByXpath(PulseTestLocators.ServerGroups.serverGrpsRadioXpath));
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrpsRadioXpath);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrp1Xpath);
    verifyElementAttributeById(PulseTestLocators.ServerGroups.serverGrp1Id, "style",
        "width: 720px; height: 415px;");
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrp1Xpath);
    verifyElementAttributeById(PulseTestLocators.ServerGroups.serverGrp1Id, "style",
        "width: 239.667px; height: 399px;");

    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrp2Xpath);
    verifyElementAttributeById(PulseTestLocators.ServerGroups.serverGrp2Id, "style",
        "width: 720px; height: 415px;");
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrp2Xpath);
    verifyElementAttributeById(PulseTestLocators.ServerGroups.serverGrp2Id, "style",
        "width: 239.667px; height: 399px;");

    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrp3Xpath);
    verifyElementAttributeById(PulseTestLocators.ServerGroups.serverGrp3Id, "style",
        "width: 720px; height: 415px;");
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrp3Xpath);
    verifyElementAttributeById(PulseTestLocators.ServerGroups.serverGrp3Id, "style",
        "width: 239.667px; height: 399px;");
  }

  @Test
  public void verifyMembersInServGrpTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrpsRadioXpath);

    verifyTextPresrntById(PulseTestLocators.ServerGroups.serverGrp1Id, "SG1");
    verifyTextPresrntById(PulseTestLocators.ServerGroups.serverGrp2Id, "SG2");
    verifyTextPresrntById(PulseTestLocators.ServerGroups.serverGrp3Id, "SG3");

    verifyTextPresrntById(PulseTestLocators.ServerGroups.sg1M1Id, "M1");
    verifyTextPresrntById(PulseTestLocators.ServerGroups.sg1M2Id, "M2");
    verifyTextPresrntById(PulseTestLocators.ServerGroups.sg1M3Id, "M3");

    verifyTextPresrntById(PulseTestLocators.ServerGroups.sg2M1Id, "M1");
    verifyTextPresrntById(PulseTestLocators.ServerGroups.sg2M2Id, "M2");

    verifyTextPresrntById(PulseTestLocators.ServerGroups.sg3M3Id, "M3");
  }

  @Test
  public void memberNavigationFromServGrpTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.serverGrpsRadioXpath);
    clickElementUsingId(PulseTestLocators.ServerGroups.sg1M1Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.sg1M2Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.sg1M3Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.sg2M1Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.sg2M2Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.sg3M3Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
  }

  @Test
  public void clickServGrpGridButtonShowsGridTest() {
    navigateToServerGroupGridView();
    verifyElementPresentByXpath(PulseTestLocators.ServerGroups.idSG1M3Xpath);
    verifyElementPresentByXpath(PulseTestLocators.ServerGroups.idSG1M2Xpath);
    verifyElementPresentByXpath(PulseTestLocators.ServerGroups.idSG1M1Xpath);
    verifyElementPresentByXpath(PulseTestLocators.ServerGroups.nameM3Xpath);
    verifyElementPresentByXpath(PulseTestLocators.ServerGroups.nameM2Xpath);
    verifyElementPresentByXpath(PulseTestLocators.ServerGroups.nameM1Xpath);

  }

  @Test
  public void memberNavigationFromServGrpGridTest() {
    navigateToServerGroupGridView();
    clickElementUsingXpath(PulseTestLocators.ServerGroups.idSG1M3Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
    navigateToServerGroupGridView();
    clickElementUsingXpath(PulseTestLocators.ServerGroups.idSG1M1Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    navigateToServerGroupGridView();
    clickElementUsingXpath(PulseTestLocators.ServerGroups.idSG1M2Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
  }

  @Test
  public void verifyZonePresentTest() {
    navigateToRedundancyZonesTreeView();
    verifyElementPresentByXpath(PulseTestLocators.RedundancyZone.zoneRZ1RZ2Xpath);
    verifyElementPresentById(PulseTestLocators.RedundancyZone.zoneRZ2Id);
  }

  @Ignore("Fails for unknown reason when run using gradle on command line")
  @Test
  public void expandAndCloseRdncyZoneTest() {
    navigateToRedundancyZonesTreeView();
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.zoneRZ1RZ2Xpath);
    verifyElementAttributeById(PulseTestLocators.RedundancyZone.zoneRZ1Id, "style",
        "width: 720px; height: 415px;");
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.zoneRZ1RZ2Xpath);
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.zoneRZ2Xpath);
    verifyElementAttributeById(PulseTestLocators.RedundancyZone.zoneRZ2Id, "style",
        "width: 720px; height: 415px;");

  }

  @Test
  public void clickRZMembersNavigationTest() {
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.m1RZ1RZ2Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.m2RZ1Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.m3RZ2Id);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
  }

  @Test
  public void clickRZGridShowingGridTest() {
    navigateToRedundancyZonesGridView();
    verifyElementPresentByXpath(PulseTestLocators.RedundancyZone.idM2Xpath);
    verifyElementPresentByXpath(PulseTestLocators.RedundancyZone.idM1Xpath);
    verifyElementPresentByXpath(PulseTestLocators.RedundancyZone.idM3Xpath);
    verifyTextPresrntByXpath(PulseTestLocators.RedundancyZone.idM2Xpath, "M2");
    verifyTextPresrntByXpath(PulseTestLocators.RedundancyZone.idM1Xpath, "M1");
    verifyTextPresrntByXpath(PulseTestLocators.RedundancyZone.idM3Xpath, "M3");
  }

  @Test
  public void clickRZGridMembersNavigationTest() {
    navigateToRedundancyZonesGridView();
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.idM2Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M2");
    navigateToRedundancyZonesGridView();
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.idM1Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M1");
    navigateToRedundancyZonesGridView();
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.idM3Xpath);
    verifyTextPresrntById(PulseTestLocators.RegionDetailsView.memberNameId, "M3");
  }


  @Test
  public void verifySortingOptionsTest() {
    clickElementUsingXpath(PulseTestLocators.TopNavigation.clusterViewLinkXpath);
    clickElementUsingId(PulseTestLocators.TopologyView.treeMapButtonId);
    verifyElementPresentById(PulseTestLocators.TopologyView.hotSpotId);
    clickElementUsingId(PulseTestLocators.TopologyView.hotSpotId);
    verifyElementPresentByLinkText("Heap Usage");
    verifyElementPresentByLinkText("CPU Usage");
  }

  /*
   * HotSpot test scripts -
   */
  // --- Topology view

  @Test
  public void testHotSpotOptPrsntOnTopologyView() {
    navigateToTopologyTreeView();
    Assert.assertEquals(PulseTestData.Topology.hotSpotHeapLbl,
        getTextUsingId(PulseTestLocators.TopologyView.hotSpotId));
  }

  @Test
  public void testHotSpotOptionsTopologyView() {
    navigateToTopologyTreeView();
    clickElementUsingId(PulseTestLocators.TopologyView.hotSpotId);
    assertEquals(PulseTestData.Topology.hotSpotHeapLbl,
        getTextUsingXpath(PulseTestLocators.TopologyView.heapUsageXpath));
    assertEquals(PulseTestData.Topology.hotSpotCPULbl,
        getTextUsingXpath(PulseTestLocators.TopologyView.cpuUsageXpath));
  }

  @Test
  public void testCpuUsageNavigationOnTopologyView() {
    navigateToTopologyTreeView();
    clickElementUsingId(PulseTestLocators.TopologyView.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.cpuUsageXpath);
    assertEquals(PulseTestData.Topology.hotSpotCPULbl,
        getTextUsingId(PulseTestLocators.TopologyView.hotSpotId));
  }

  @Test
  public void testHeapUsageNavigationOnTopologyView() {
    navigateToTopologyTreeView();
    clickElementUsingId(PulseTestLocators.TopologyView.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.heapUsageXpath);
    assertEquals(PulseTestData.Topology.hotSpotHeapLbl,
        getTextUsingId(PulseTestLocators.TopologyView.hotSpotId));
  }

  @Test
  public void testSortingUsingCpuUsageOnTopologyView() {
    navigateToTopologyTreeView();
    clickElementUsingId(PulseTestLocators.TopologyView.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.cpuUsageXpath);
    assertMemberSortingByCpuUsage();
  }

  @Test
  public void testSortingUsingHeapUsageOnTopologyView() {
    navigateToTopologyTreeView();
    clickElementUsingId(PulseTestLocators.TopologyView.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.TopologyView.heapUsageXpath);
    assertMemberSortingByHeapUsage();
  }

  // --- Server Group view

  @Test
  public void testHotSpotOptPrsntOnServerGroupView() {
    navigateToServerGroupTreeView();
    assertEquals(PulseTestData.ServerGroups.hotSpotHeapLbl,
        getTextUsingId(PulseTestLocators.ServerGroups.hotSpotId));
  }

  @Test
  public void testHotSpotOptionsServerGroupView() {
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.hotSpotId);
    assertEquals(PulseTestData.ServerGroups.hotSpotHeapLbl,
        getTextUsingXpath(PulseTestLocators.ServerGroups.heapUsageXpath));
    assertEquals(PulseTestData.ServerGroups.hotSpotCPULbl,
        getTextUsingXpath(PulseTestLocators.ServerGroups.cpuUsageXpath));
  }

  @Test
  public void testCpuUsageNavigationOnServerGroupView() {
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.cpuUsageXpath);
    assertEquals(PulseTestData.ServerGroups.hotSpotCPULbl,
        getTextUsingId(PulseTestLocators.ServerGroups.hotSpotId));
  }

  @Test
  public void testHeapUsageNavigationOnServerGroupView() {
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.heapUsageXpath);
    assertEquals(PulseTestData.ServerGroups.hotSpotHeapLbl,
        getTextUsingId(PulseTestLocators.ServerGroups.hotSpotId));
  }

  @Test
  public void testSortingUsingHeapUsageOnServerGroupView() {
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.heapUsageXpath);
    assertMemberSortingBySgHeapUsage();
  }

  @Test
  public void testSortingUsingCpuUsageOnServerGroupView() {
    navigateToServerGroupTreeView();
    clickElementUsingId(PulseTestLocators.ServerGroups.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.ServerGroups.cpuUsageXpath);
    assertMemberSortingBySgCpuUsage();
  }

  // --- Redundancy Zone view

  @Test
  public void testHotSpotOptPrsntOnRedundancyZoneView() {
    navigateToRedundancyZonesTreeView();
    assertEquals(PulseTestData.RedundancyZone.hotSpotHeapLbl,
        getTextUsingId(PulseTestLocators.RedundancyZone.hotSpotId));
  }


  @Test
  public void testHotSpotOptionsRedundancyZoneView() {
    // navigate to Redundancy Zones - Tree View
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.hotSpotId);
    assertEquals(PulseTestData.RedundancyZone.hotSpotHeapLbl,
        getTextUsingXpath(PulseTestLocators.RedundancyZone.heapUsageXpath));
    assertEquals(PulseTestData.RedundancyZone.hotSpotCPULbl,
        getTextUsingXpath(PulseTestLocators.RedundancyZone.cpuUsageXpath));
  }

  @Test
  public void testCpuUsageNavigationOnRedundancyZoneView() {
    // navigate to Redundancy Zones - Tree View
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.cpuUsageXpath);
    assertEquals(PulseTestData.RedundancyZone.hotSpotCPULbl,
        getTextUsingId(PulseTestLocators.RedundancyZone.hotSpotId));
  }

  @Test
  public void testHeapUsageNavigationOnRedundancyZoneView() {
    // navigate to Redundancy Zones - Tree View
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.heapUsageXpath);
    assertEquals(PulseTestData.RedundancyZone.hotSpotHeapLbl,
        getTextUsingId(PulseTestLocators.RedundancyZone.hotSpotId));
  }

  @Test
  public void testSortingUsingHeapUsageOnRedundancyView() {
    // navigate to Redundancy Zones - Tree View
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.heapUsageXpath);
    assertMemberSortingByRzHeapUsage();
  }

  @Test
  public void testSortingUsingCpuUsageOnRedundancyView() {
    // navigate to Redundancy Zones - Tree View
    navigateToRedundancyZonesTreeView();
    clickElementUsingId(PulseTestLocators.RedundancyZone.hotSpotId);
    clickElementUsingXpath(PulseTestLocators.RedundancyZone.cpuUsageXpath);
    assertMemeberSortingByRzCpuUsage();
  }

  @Test
  public void testDataBrowserFilterFeature() {
    // navigate to Data browser page
    loadDataBrowserpage();
    List<WebElement> regionLst = getRegionsFromDataBrowser();
    String[] regionNames = new String[regionLst.size()];
    for (int regionIndex = 0; regionIndex < regionLst.size(); regionIndex++) {
      regionNames[regionIndex] = findElementByXpath(PulseTestLocators.DataBrowser.rgnSpanFirstPart
          + (regionIndex + 1) + PulseTestLocators.DataBrowser.rgnSpanSecondPart).getText();
    }
    // type each region name in region filter and verify respective region(s) are displayed in
    // region list
    for (String region : regionNames) {
      waitForElementWithId(PulseTestLocators.DataBrowser.rgnFilterTxtBoxId).clear();
      waitForElementWithId(PulseTestLocators.DataBrowser.rgnFilterTxtBoxId).sendKeys(region);

      List<WebElement> regionLst1 = getRegionsFromDataBrowser();

      for (int regionIndex = 1; regionIndex <= regionLst1.size(); regionIndex++) {
        assertEquals(region, findElementByXpath(PulseTestLocators.DataBrowser.rgnSpanFirstPart
            + regionIndex + PulseTestLocators.DataBrowser.rgnSpanSecondPart).getText());
      }
    }
  }

  @Test
  public void testDataBrowserFilterPartialRegionName() {
    // navigate to Data browser page
    loadDataBrowserpage();
    waitForElementWithId(PulseTestLocators.DataBrowser.rgnFilterTxtBoxId).clear();

    // type partial region name in region filter and verify that all the regions that contains that
    // text displays
    waitForElementWithId(PulseTestLocators.DataBrowser.rgnFilterTxtBoxId)
        .sendKeys(PulseTestData.DataBrowser.partialRgnName);
    List<WebElement> regionLst = getRegionsFromDataBrowser();

    for (int regionIndex = 0; regionIndex < regionLst.size(); regionIndex++) {
      assertTrue(findElementByXpath(PulseTestLocators.DataBrowser.rgnSpanFirstPart
          + (regionIndex + 1) + PulseTestLocators.DataBrowser.rgnSpanSecondPart).getText()
              .contains(PulseTestData.DataBrowser.partialRgnName));
    }
  }

  @Test
  public void testDataBrowserClearButton() {
    // navigate to Data browser page
    loadDataBrowserpage();

    sendKeysUsingId(PulseTestLocators.DataBrowser.queryEditorTxtBoxId,
        PulseTestData.DataBrowser.query1Text);
    String editorTextBeforeClear =
        getTextUsingId(PulseTestLocators.DataBrowser.queryEditorTxtBoxId);
    clickElementUsingXpath(PulseTestLocators.DataBrowser.btnClearXpath);
    String editorTextAfterClear = getTextUsingId(PulseTestLocators.DataBrowser.queryEditorTxtBoxId);

    assertNotEquals(PulseTestData.DataBrowser.query1Text, editorTextAfterClear);
  }

  @Ignore("WIP") // Data Browser's Query History not showing any data on button click, therefore
                 // this test is failing
  @Test
  public void testDataBrowserHistoryQueue() {
    // navigate to Data browser page
    loadDataBrowserpage();

    List<WebElement> numOfReg = webDriverRule.getDriver()
        .findElements(By.xpath(PulseTestLocators.DataBrowser.divDataRegions));

    for (int i = 1; i <= numOfReg.size(); i++) {
      if (getTextUsingId("treeDemo_" + i + "_span").equals(PulseTestData.DataBrowser.regName)) {
        searchByIdAndClick("treeDemo_" + i + "_check"); // driver.findElement(By.id("treeDemo_" + i
                                                        // + "_check")).click();
      }
    }

    sendKeysUsingId(PulseTestLocators.DataBrowser.queryEditorTxtBoxId,
        DataBrowserResultLoader.QUERY_TYPE_ONE);
    clickElementUsingId(PulseTestLocators.DataBrowser.btnExecuteQueryId);

    // Get required datetime format and extract date and hours from date time.
    DateFormat dateFormat = new SimpleDateFormat(PulseTestData.DataBrowser.datePattern);
    String queryDateTime = dateFormat.format(System.currentTimeMillis());
    String[] queryTime = queryDateTime.split(":");
    System.out.println("Query Time from System: " + queryTime[0]);


    clickElementUsingId(PulseTestLocators.DataBrowser.historyIcon);
    List<WebElement> historyLst =
        webDriverRule.getDriver().findElements(By.xpath(PulseTestLocators.DataBrowser.historyLst));
    String queryText = findElementByXpath(PulseTestLocators.DataBrowser.historyLst)
        .findElement(By.cssSelector(PulseTestLocators.DataBrowser.queryText)).getText();
    String historyDateTime = findElementByXpath(PulseTestLocators.DataBrowser.historyLst)
        .findElement(By.cssSelector(PulseTestLocators.DataBrowser.historyDateTime)).getText();
    System.out.println("Query Text from History Table: " + queryText);
    System.out.println("Query Time from History Table: " + historyDateTime);
    // verify the query text, query datetime in history panel
    assertThat(queryText).isEqualTo(DataBrowserResultLoader.QUERY_TYPE_ONE);
    assertThat(historyDateTime).contains(queryTime[0]);
  }

  @Test
  public void testDataBrowserHTMLEncode() {
    // navigate to Data browser page
    loadDataBrowserpage();

    WebDriver driver = webDriverRule.getDriver();
    List<WebElement> numOfReg = driver
        .findElements(By.xpath(PulseTestLocators.DataBrowser.divDataRegions));

    for (int i = 1; i <= numOfReg.size(); i++) {
      if (getTextUsingId("treeDemo_" + i + "_span").equals(PulseTestData.DataBrowser.regName)) {
        searchByIdAndClick("treeDemo_" + i + "_check"); // driver.findElement(By.id("treeDemo_" + i
        // + "_check")).click();
      }
    }

    sendKeysUsingId(PulseTestLocators.DataBrowser.queryEditorTxtBoxId,
        DataBrowserResultLoader.QUERY_TYPE_EIGHT);
    clickElementUsingId(PulseTestLocators.DataBrowser.btnExecuteQueryId);

    clickElementUsingId(PulseTestLocators.DataBrowser.historyIcon);
    String queryText = findElementByXpath(PulseTestLocators.DataBrowser.historyLst)
        .findElement(By.cssSelector(PulseTestLocators.DataBrowser.queryText)).getText();

    assertThat(queryText).isEqualTo(DataBrowserResultLoader.QUERY_TYPE_EIGHT);

    List<WebElement> elements =
        driver.findElements(By.xpath(PulseTestData.DataBrowser.resultClusterHeadingsXPath));
    List<WebElement> filteredElements = elements.stream().filter(webElement -> webElement.getText()
        .equals("org.apache.geode.cache.query.data.Portfolio")).collect(
            Collectors.toList());
    List<WebElement> finalElements = filteredElements.stream().map(webElement -> {
      webElement.click();
      return webElement.findElements(By.xpath(PulseTestData.DataBrowser.resultClusterCellXPath));
    }).flatMap(Collection::stream).collect(Collectors.toList());

    // confirm script text is displayed
    assertThat(finalElements).hasSize(2);
    finalElements.forEach(webElement -> {
      assertThat(webElement.getAttribute("title")).isEqualTo("<script>alert('xss')</script>");
    });
  }
}
