Repository: provectus/kafka-ui
Issue: [e2e] Checking the existing Broker's profile in a cluster
Labels: scope/QA
scope/AQA

Autotest implementation for:

https://app.qase.io/case/KAFKAUI-85

Description:
Checking the information of used Broker in a cluster

Pre-conditions:
Login to Kafka-ui
Open the cluster

Post-conditions:
Empty value

Steps:
1 Press the Brokers component
2 Click on Broker

Expected result:
1 All the existing brokers should be displayed with different rows
2 The Broker's profile should open with following information:  Segment Size, Segment Count, Port, Host, Name, Error, Topics, 
   Partitions.
   




Issue comments:

Pull request review comments:
why do we need this annotation?
why do we need this annotation?
extra space
getVisibleSummaryCellL -> getVisibleSummaryCells
can we simplify this way?
return getEnabledColumnHeaders();
really enabled?
here and at 39 line we need to specify element.getSearchCriteria() + " isVisibleOrEnabled()" as we used in com.provectus.kafka.ui.suite.topics.TopicActionsTests.checkTopicListElements, because if some element(s) will fail assertion we'll know which one(s) only this way
Fixed.
Fixed.
Fixed.
Fixed.
Fixed.
Fixed.
Fixed.

Patch that resolved the issue:
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/BasePage.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/BasePage.java
index 827a663cc51..de733b668f9 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/BasePage.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/BasePage.java
@@ -16,7 +16,9 @@ public abstract class BasePage extends WebUtils {
   protected SelenideElement dotMenuBtn = $x("//button[@aria-label='Dropdown Toggle']");
   protected SelenideElement alertHeader = $x("//div[@role='alert']//div[@role='heading']");
   protected SelenideElement alertMessage = $x("//div[@role='alert']//div[@role='contentinfo']");
+  protected String summaryCellLocator = "//div[contains(text(),'%s')]";
   protected String tableElementNameLocator = "//tbody//a[contains(text(),'%s')]";
+  protected String сolumnHeaderLocator = "//table//tr/th/div[text()='%s']";
 
   protected void waitUntilSpinnerDisappear() {
     log.debug("\nwaitUntilSpinnerDisappear");
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersDetails.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersDetails.java
new file mode 100644
index 00000000000..8ae28c0944e
--- /dev/null
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersDetails.java
@@ -0,0 +1,56 @@
+package com.provectus.kafka.ui.pages.brokers;
+
+import static com.codeborne.selenide.Selenide.$x;
+
+import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.SelenideElement;
+import com.provectus.kafka.ui.pages.BasePage;
+import io.qameta.allure.Step;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class BrokersDetails extends BasePage {
+
+  protected SelenideElement logDirectoriesTab = $x("//a[text()='Log directories']");
+  protected SelenideElement metricsTab = $x("//a[text()='Metrics']");
+
+  @Step
+  public BrokersDetails waitUntilScreenReady() {
+    waitUntilSpinnerDisappear();
+    Arrays.asList(logDirectoriesTab, metricsTab).forEach(element -> element.shouldBe(Condition.visible));
+    return this;
+  }
+
+  private List<SelenideElement> getVisibleColumnHeaders() {
+    return Stream.of("Name", "Topics", "Error", "Partitions")
+        .map(name -> $x(String.format(сolumnHeaderLocator, name)))
+        .collect(Collectors.toList());
+  }
+
+  private List<SelenideElement> getEnabledColumnHeaders() {
+    return Stream.of("Name", "Error")
+        .map(name -> $x(String.format(сolumnHeaderLocator, name)))
+        .collect(Collectors.toList());
+  }
+
+  private List<SelenideElement> getVisibleSummaryCells() {
+    return Stream.of("Segment Size", "Segment Count", "Port", "Host")
+        .map(name -> $x(String.format(summaryCellLocator, name)))
+        .collect(Collectors.toList());
+  }
+
+  @Step
+  public List<SelenideElement> getAllEnabledElements() {
+    return getEnabledColumnHeaders();
+  }
+
+  @Step
+  public List<SelenideElement> getAllVisibleElements() {
+    List<SelenideElement> visibleElements = new ArrayList<>(getVisibleSummaryCells());
+    visibleElements.addAll(getVisibleColumnHeaders());
+    return visibleElements;
+  }
+}
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersList.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersList.java
new file mode 100644
index 00000000000..0d9ee67492c
--- /dev/null
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersList.java
@@ -0,0 +1,32 @@
+package com.provectus.kafka.ui.pages.brokers;
+
+import static com.codeborne.selenide.Selenide.$x;
+
+import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.SelenideElement;
+import com.provectus.kafka.ui.pages.BasePage;
+import io.qameta.allure.Step;
+
+public class BrokersList extends BasePage {
+
+  protected SelenideElement brokersListHeader = $x("//h1[text()='Brokers']");
+
+  @Step
+  public BrokersList waitUntilScreenReady() {
+    waitUntilSpinnerDisappear();
+    brokersListHeader.shouldBe(Condition.visible);
+    return this;
+  }
+
+  @Step
+  public boolean isBrokerVisible(String brokerId) {
+    tableGrid.shouldBe(Condition.visible);
+    return isVisible(getTableElement(brokerId));
+  }
+
+  @Step
+  public BrokersList openBroker(String brokerName) {
+    getTableElement(brokerName).shouldBe(Condition.enabled).click();
+    return this;
+  }
+}
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicsList.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicsList.java
index cd61bd72721..4ce2721d6fd 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicsList.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicsList.java
@@ -21,7 +21,6 @@ public class TopicsList extends BasePage {
     protected SelenideElement addTopicBtn = $x("//button[normalize-space(text()) ='Add a Topic']");
     protected SelenideElement searchField = $x("//input[@placeholder='Search by Topic Name']");
     protected SelenideElement showInternalRadioBtn = $x("//input[@name='ShowInternalTopics']");
-    protected String сolumnHeaderLocator = "//table//tr/th/div[text()='%s']";
     protected String actionButtonLocator = "//button[text()='%s']";
 
     @Step
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WebUtils.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WebUtils.java
index e35cad9769a..35a0a06f7a5 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WebUtils.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WebUtils.java
@@ -1,5 +1,7 @@
 package com.provectus.kafka.ui.utilities;
 
+import static com.codeborne.selenide.Selenide.executeJavaScript;
+
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.SelenideElement;
 import com.codeborne.selenide.WebDriverRunner;
@@ -7,44 +9,42 @@
 import org.openqa.selenium.Keys;
 import org.openqa.selenium.interactions.Actions;
 
-import static com.codeborne.selenide.Selenide.executeJavaScript;
-
 @Slf4j
 public class WebUtils {
 
-    public static void clickByActions(SelenideElement element) {
-        log.debug("\nclickByActions: {}", element.getSearchCriteria());
-        element.shouldBe(Condition.enabled);
-        new Actions(WebDriverRunner.getWebDriver())
-                .moveToElement(element)
-                .click(element)
-                .perform();
-    }
+  public static void clickByActions(SelenideElement element) {
+    log.debug("\nclickByActions: {}", element.getSearchCriteria());
+    element.shouldBe(Condition.enabled);
+    new Actions(WebDriverRunner.getWebDriver())
+        .moveToElement(element)
+        .click(element)
+        .perform();
+  }
 
-    public static void clickByJavaScript(SelenideElement element) {
-        log.debug("\nclickByJavaScript: {}", element.getSearchCriteria());
-        element.shouldBe(Condition.enabled);
-        String script = "arguments[0].click();";
-        executeJavaScript(script, element);
-    }
+  public static void clickByJavaScript(SelenideElement element) {
+    log.debug("\nclickByJavaScript: {}", element.getSearchCriteria());
+    element.shouldBe(Condition.enabled);
+    String script = "arguments[0].click();";
+    executeJavaScript(script, element);
+  }
 
-    public static void clearByKeyboard(SelenideElement field) {
-        log.debug("\nclearByKeyboard: {}", field.getSearchCriteria());
-        field.shouldBe(Condition.enabled).sendKeys(Keys.END);
-        field.sendKeys(Keys.chord(Keys.CONTROL + "a"), Keys.DELETE);
-    }
+  public static void clearByKeyboard(SelenideElement field) {
+    log.debug("\nclearByKeyboard: {}", field.getSearchCriteria());
+    field.shouldBe(Condition.enabled).sendKeys(Keys.END);
+    field.sendKeys(Keys.chord(Keys.CONTROL + "a"), Keys.DELETE);
+  }
 
-    public static boolean isVisible(SelenideElement element) {
-        log.debug("\nisVisible: {}", element.getSearchCriteria());
-        boolean isVisible = false;
-        try {
-            element.shouldBe(Condition.visible);
-            isVisible = true;
-        } catch (Throwable e) {
-            log.debug("{} is not visible", element.getSearchCriteria());
-        }
-        return isVisible;
+  public static boolean isVisible(SelenideElement element) {
+    log.debug("\nisVisible: {}", element.getSearchCriteria());
+    boolean isVisible = false;
+    try {
+      element.shouldBe(Condition.visible);
+      isVisible = true;
+    } catch (Throwable e) {
+      log.debug("{} is not visible", element.getSearchCriteria());
     }
+    return isVisible;
+  }
 
   public static boolean isEnabled(SelenideElement element) {
     log.debug("\nisEnabled: {}", element.getSearchCriteria());


Test patch:
diff --git a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/Facade.java b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/Facade.java
index 5b9533c30ec..279704b8b95 100644
--- a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/Facade.java
+++ b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/Facade.java
@@ -3,6 +3,8 @@
 import com.provectus.kafka.ui.helpers.ApiHelper;
 import com.provectus.kafka.ui.pages.NaviSideBar;
 import com.provectus.kafka.ui.pages.TopPanel;
+import com.provectus.kafka.ui.pages.brokers.BrokersDetails;
+import com.provectus.kafka.ui.pages.brokers.BrokersList;
 import com.provectus.kafka.ui.pages.connector.ConnectorCreateForm;
 import com.provectus.kafka.ui.pages.connector.ConnectorDetails;
 import com.provectus.kafka.ui.pages.connector.KafkaConnectList;
@@ -32,4 +34,6 @@ public abstract class Facade {
     protected ConsumersList consumersList = new ConsumersList();
     protected NaviSideBar naviSideBar = new NaviSideBar();
     protected TopPanel topPanel = new TopPanel();
+    protected BrokersList brokersList = new BrokersList();
+    protected BrokersDetails brokersDetails = new BrokersDetails();
 }
diff --git a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/brokers/BrokersTests.java b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/brokers/BrokersTests.java
new file mode 100644
index 00000000000..5a493438f98
--- /dev/null
+++ b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/brokers/BrokersTests.java
@@ -0,0 +1,42 @@
+package com.provectus.kafka.ui.suite.brokers;
+
+import static com.provectus.kafka.ui.pages.NaviSideBar.SideMenuOption.BROKERS;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.codeborne.selenide.Condition;
+import com.provectus.kafka.ui.base.BaseTest;
+import com.provectus.kafka.ui.utilities.qaseIoUtils.annotations.AutomationStatus;
+import com.provectus.kafka.ui.utilities.qaseIoUtils.annotations.Suite;
+import com.provectus.kafka.ui.utilities.qaseIoUtils.enums.Status;
+import io.qase.api.annotation.CaseId;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class BrokersTests extends BaseTest {
+  private static final String SUITE_TITLE = "Brokers";
+  private static final long SUITE_ID = 1;
+
+  @DisplayName("Checking the existing Broker's profile in a cluster")
+  @Suite(suiteId = SUITE_ID, title = SUITE_TITLE)
+  @AutomationStatus(status = Status.AUTOMATED)
+  @CaseId(85)
+  @Test
+  public void checkExistingBrokersInCluster(){
+    naviSideBar
+        .openSideMenu(BROKERS);
+    brokersList
+        .waitUntilScreenReady();
+    assertThat(brokersList.isBrokerVisible("1")).as("isBrokerVisible()").isTrue();
+    brokersList
+        .openBroker("1");
+    brokersDetails
+        .waitUntilScreenReady();
+    SoftAssertions softly = new SoftAssertions();
+    brokersDetails.getAllVisibleElements().forEach(element -> softly.assertThat(element.is(Condition.visible))
+        .as(element.getSearchCriteria() + " isVisible()").isTrue());
+    brokersDetails.getAllEnabledElements().forEach(element -> softly.assertThat(element.is(Condition.enabled))
+        .as(element.getSearchCriteria() + " isEnabled()").isTrue());
+    softly.assertAll();
+  }
+}