/*
 * 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();
