Repository: provectus/kafka-ui
Issue: [e2e]Checking Compare Versions operation for Schema
Labels: scope/QA
scope/AQA

**Autotest implementation for:**

https://app.qase.io/case/KAFKAUI-44

**Description:**
The purpose of this case is to check the Compare Versions operation for Schemas

**Pre-conditions:**
- Login to Kafka-ui
- Navigate to Schema Registry
- Open the Schema

**Post-conditions:**
Empty value

**Steps:**

1. Press "Compare Versions" button 

**Expected result:**
 Compare page should open with 2 column

2. Press "Version *" dropdown

**Expected result:**
All the existing versions should be listed

3. Select different versions to compare

**Expected result:**
All the changes should be highlighted

Issue comments:

Pull request review comments:
elementLocatorDdl -> ddlElementLocator
here we can use primitive: Integer -> int
getAllMarkedLines -> getMarkedLinesNumber
selectVersionFromLeftDropDown - just left?
versionNumberDd -> version
remove pls
extra space
this method and it's object also aren't used
why did we add them?
u've just deleted deleteSchemaAvro??
refactored to int 

done

discussed 
ye , sorry 
done
discussed 
ye , sorry it my fail
done 
seems we can create method openSchemaVersionDdl()
then getVersionsNumberFromList() and after this assertion selectVersionFromDdl() - without schemaVersionDdl.shouldBe(Condition.enabled).click();
done 
can we not use duplicates this way?
int latestVersion = schemaDetails
.waitUntilScreenReady()
.getLatestVersion();
can we not use duplicates this way?
int latestVersion = schemaCreateForm
.waitUntilScreenReady()
.openSchemaVersionDdl()
.getVersionsNumberFromList();
Compare versions is failed -> Versions number is not matched
countOfElementsDd -> versionsNumberFromDdl
done
done
done
done


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 de733b668f9..069b1b41dda 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
@@ -18,7 +18,7 @@ public abstract class BasePage extends WebUtils {
   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 String columnHeaderLocator = "//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
index 8ae28c0944e..77fc9e0b41c 100644
--- 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
@@ -26,13 +26,13 @@ public BrokersDetails waitUntilScreenReady() {
 
   private List<SelenideElement> getVisibleColumnHeaders() {
     return Stream.of("Name", "Topics", "Error", "Partitions")
-        .map(name -> $x(String.format(сolumnHeaderLocator, name)))
+        .map(name -> $x(String.format(columnHeaderLocator, name)))
         .collect(Collectors.toList());
   }
 
   private List<SelenideElement> getEnabledColumnHeaders() {
     return Stream.of("Name", "Error")
-        .map(name -> $x(String.format(сolumnHeaderLocator, name)))
+        .map(name -> $x(String.format(columnHeaderLocator, name)))
         .collect(Collectors.toList());
   }
 
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/KafkaConnectList.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/KafkaConnectList.java
index 316178d1d22..b86734b2dc6 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/KafkaConnectList.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/KafkaConnectList.java
@@ -5,12 +5,9 @@
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.SelenideElement;
 import com.provectus.kafka.ui.pages.BasePage;
-import com.provectus.kafka.ui.utilities.WaitUtils;
 import io.qameta.allure.Step;
-import lombok.experimental.ExtensionMethod;
 
 
-@ExtensionMethod(WaitUtils.class)
 public class KafkaConnectList extends BasePage {
 
     protected SelenideElement createConnectorBtn = $x("//button[contains(text(),'Create Connector')]");
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaCreateForm.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaCreateForm.java
index ec6455fcfa2..7d0d5c58a93 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaCreateForm.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaCreateForm.java
@@ -1,6 +1,7 @@
 package com.provectus.kafka.ui.pages.schema;
 
 import static com.codeborne.selenide.Selenide.$;
+import static com.codeborne.selenide.Selenide.$$x;
 import static com.codeborne.selenide.Selenide.$x;
 
 import com.codeborne.selenide.Condition;
@@ -9,6 +10,7 @@
 import com.provectus.kafka.ui.api.model.SchemaType;
 import com.provectus.kafka.ui.pages.BasePage;
 import io.qameta.allure.Step;
+import java.util.List;
 
 public class SchemaCreateForm extends BasePage {
 
@@ -19,7 +21,10 @@ public class SchemaCreateForm extends BasePage {
     protected SelenideElement schemaTypeDdl = $x("//ul[@name='schemaType']");
     protected SelenideElement compatibilityLevelList = $x("//ul[@name='compatibilityLevel']");
     protected SelenideElement newSchemaTextArea = $x("//div[@id='newSchema']");
-    protected String elementLocatorDdl = "//li[@value='%s']";
+    protected SelenideElement schemaVersionDdl = $$x("//ul[@role='listbox']/li[text()='Version 2']").first();
+    protected List<SelenideElement> visibleMarkers = $$x("//div[@class='ace_scroller']//div[contains(@class,'codeMarker')]");
+    protected List<SelenideElement> elementsCompareVersionDdl = $$x("//ul[@role='listbox']/ul/li");
+    protected String ddlElementLocator = "//li[@value='%s']";
 
     @Step
     public SchemaCreateForm waitUntilScreenReady(){
@@ -43,7 +48,7 @@ public SchemaCreateForm setSchemaField(String text) {
     @Step
     public SchemaCreateForm selectSchemaTypeFromDropdown(SchemaType schemaType) {
         schemaTypeDdl.shouldBe(Condition.enabled).click();
-        $x(String.format(elementLocatorDdl, schemaType.getValue())).shouldBe(Condition.visible).click();
+        $x(String.format(ddlElementLocator, schemaType.getValue())).shouldBe(Condition.visible).click();
         return this;
     }
 
@@ -56,10 +61,32 @@ public SchemaCreateForm clickSubmitButton() {
     @Step
     public SchemaCreateForm selectCompatibilityLevelFromDropdown(CompatibilityLevel.CompatibilityEnum level) {
         compatibilityLevelList.shouldBe(Condition.enabled).click();
-        $x(String.format(elementLocatorDdl, level.getValue())).shouldBe(Condition.visible).click();
+        $x(String.format(ddlElementLocator, level.getValue())).shouldBe(Condition.visible).click();
         return this;
     }
 
+    @Step
+    public SchemaCreateForm openSchemaVersionDdl(){
+      schemaVersionDdl.shouldBe(Condition.enabled).click();
+      return this;
+    }
+
+    @Step
+    public int getVersionsNumberFromList(){
+      return elementsCompareVersionDdl.size();
+    }
+
+    @Step
+    public SchemaCreateForm selectVersionFromDropDown(int versionNumberDd){
+      $x(String.format(ddlElementLocator,versionNumberDd)).shouldBe(Condition.visible).click();
+      return this;
+    }
+
+    @Step
+    public int getMarkedLinesNumber(){
+      return visibleMarkers.size();
+    }
+
     @Step
     public SchemaCreateForm setNewSchemaValue(String configJson) {
         newSchemaTextArea.shouldBe(Condition.visible).click();
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaDetails.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaDetails.java
index b9808d05405..ce211337099 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaDetails.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/schema/SchemaDetails.java
@@ -14,7 +14,9 @@ public class SchemaDetails extends BasePage {
     protected SelenideElement editSchemaBtn = $x("//button[contains(text(),'Edit Schema')]");
     protected SelenideElement removeBtn = $x("//*[contains(text(),'Remove')]");
     protected SelenideElement confirmBtn = $x("//div[@role='dialog']//button[contains(text(),'Confirm')]");
-    protected SelenideElement schemaTypeDdl = $x("//h4[contains(text(),'Type')]/../p");
+    protected SelenideElement schemaTypeField = $x("//h4[contains(text(),'Type')]/../p");
+    protected SelenideElement latestVersionField = $x("//h4[contains(text(),'Latest version')]/../p");
+    protected SelenideElement compareVersionBtn = $x("//button[text()='Compare Versions']");
     protected String schemaHeaderLocator = "//h1[contains(text(),'%s')]";
 
     @Step
@@ -34,9 +36,14 @@ public boolean isSchemaHeaderVisible(String schemaName) {
         return isVisible($x(String.format(schemaHeaderLocator,schemaName)));
     }
 
+    @Step
+    public int getLatestVersion(){
+      return Integer.parseInt(latestVersionField.getText());
+    }
+
     @Step
     public String getSchemaType() {
-        return schemaTypeDdl.getText();
+        return schemaTypeField.getText();
     }
 
     @Step
@@ -45,6 +52,12 @@ public SchemaDetails openEditSchema(){
         return this;
     }
 
+    @Step
+    public SchemaDetails openCompareVersionMenu(){
+      compareVersionBtn.shouldBe(Condition.enabled).click();
+      return this;
+    }
+
     @Step
     public SchemaDetails removeSchema() {
         clickByJavaScript(dotMenuBtn);
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicDetails.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicDetails.java
index e968d4f9372..95c3e6fb23f 100644
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicDetails.java
+++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topic/TopicDetails.java
@@ -10,15 +10,12 @@
 import com.codeborne.selenide.ElementsCollection;
 import com.codeborne.selenide.SelenideElement;
 import com.provectus.kafka.ui.pages.BasePage;
-import com.provectus.kafka.ui.utilities.WaitUtils;
 import io.qameta.allure.Step;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import lombok.experimental.ExtensionMethod;
 import org.openqa.selenium.By;
 
-@ExtensionMethod({WaitUtils.class})
 public class TopicDetails extends BasePage {
 
   protected SelenideElement clearMessagesBtn = $x(("//div[contains(text(), 'Clear messages')]"));
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 dcda2ce4dff..c32621bf1a5 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
@@ -5,16 +5,13 @@
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.SelenideElement;
 import com.provectus.kafka.ui.pages.BasePage;
-import com.provectus.kafka.ui.utilities.WaitUtils;
 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;
-import lombok.experimental.ExtensionMethod;
 
-@ExtensionMethod(WaitUtils.class)
 public class TopicsList extends BasePage {
 
     protected SelenideElement topicListHeader = $x("//*[text()='Topics']");
@@ -56,13 +53,13 @@ private List<SelenideElement> getActionButtons() {
 
     private List<SelenideElement> getVisibleColumnHeaders() {
       return Stream.of("Replication Factor","Number of messages","Topic Name", "Partitions", "Out of sync replicas", "Size")
-          .map(name -> $x(String.format(сolumnHeaderLocator, name)))
+          .map(name -> $x(String.format(columnHeaderLocator, name)))
         .collect(Collectors.toList());
     }
 
     private List<SelenideElement> getEnabledColumnHeaders(){
       return Stream.of("Topic Name", "Partitions", "Out of sync replicas", "Size")
-          .map(name -> $x(String.format(сolumnHeaderLocator, name)))
+          .map(name -> $x(String.format(columnHeaderLocator, name)))
           .collect(Collectors.toList());
     }
 
diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WaitUtils.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WaitUtils.java
deleted file mode 100644
index ec4ee223cb8..00000000000
--- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/WaitUtils.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.provectus.kafka.ui.utilities;
-
-import com.codeborne.selenide.Condition;
-import com.codeborne.selenide.SelenideElement;
-import org.junit.jupiter.api.Assertions;
-import org.openqa.selenium.By;
-
-import static com.codeborne.selenide.Selenide.*;
-import static com.codeborne.selenide.Selenide.$;
-
-public class WaitUtils {
-    public static void refreshUntil(By by, Condition condition) {
-        int i = 0;
-        do {
-            refresh();
-            i++;
-            sleep(2000);
-        } while ($$(by).size() < 1 && i != 20);
-        $(by).shouldBe(condition);
-    }
-
-    public static void waitForSelectedValue(SelenideElement element, String selectedValue) {
-        int i = 0;
-        do {
-            refresh();
-            i++;
-            sleep(2000);
-        } while (!selectedValue.equals(element.getSelectedValue()) && i != 60);
-        Assertions.assertEquals(selectedValue, element.getSelectedValue()) ;
-    }
-}


Test patch:
diff --git a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/schemas/SchemasTests.java b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/schemas/SchemasTests.java
index 553568795dd..398130bcd19 100644
--- a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/schemas/SchemasTests.java
+++ b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/suite/schemas/SchemasTests.java
@@ -103,25 +103,52 @@ void updateSchemaAvro() {
         Assertions.assertEquals(CompatibilityLevel.CompatibilityEnum.NONE.toString(), schemaDetails.getCompatibility(), "getCompatibility()");
     }
 
+    @DisplayName("Checking Compare Versions operation for Schema")
+    @Suite(suiteId = SUITE_ID, title = SUITE_TITLE)
+    @AutomationStatus(status = Status.AUTOMATED)
+    @CaseId(186)
+    @Test
+    @Order(3)
+    void compareVersionsOperation() {
+      naviSideBar
+          .openSideMenu(SCHEMA_REGISTRY);
+      schemaRegistryList
+          .waitUntilScreenReady()
+          .openSchema(AVRO_API.getName());
+      int latestVersion = schemaDetails
+          .waitUntilScreenReady()
+          .getLatestVersion();
+      schemaDetails
+          .openCompareVersionMenu();
+      int versionsNumberFromDdl = schemaCreateForm
+          .waitUntilScreenReady()
+          .openSchemaVersionDdl()
+          .getVersionsNumberFromList();
+      Assertions.assertEquals(latestVersion,versionsNumberFromDdl,"Versions number is not matched");
+      schemaCreateForm
+          .selectVersionFromDropDown(1);
+      Assertions.assertEquals(53, schemaCreateForm.getMarkedLinesNumber(), "getAllMarkedLines()");
+    }
+
     @DisplayName("should delete AVRO schema")
     @Suite(suiteId = SUITE_ID, title = SUITE_TITLE)
     @AutomationStatus(status = Status.AUTOMATED)
     @CaseId(187)
     @Test
-    @Order(3)
+    @Order(4)
     void deleteSchemaAvro() {
-        naviSideBar
-                .openSideMenu(SCHEMA_REGISTRY);
-        schemaRegistryList
-                .waitUntilScreenReady()
-                .openSchema(AVRO_API.getName());
-        schemaDetails
-                .waitUntilScreenReady()
-                .removeSchema();
-        schemaRegistryList
-                .waitUntilScreenReady();
-        Assertions.assertFalse(schemaRegistryList.isSchemaVisible(AVRO_API.getName()),"isSchemaVisible()");
-        SCHEMA_LIST.remove(AVRO_API);
+      naviSideBar
+          .openSideMenu(SCHEMA_REGISTRY);
+      schemaRegistryList
+          .waitUntilScreenReady()
+          .openSchema(AVRO_API.getName());
+      schemaDetails
+          .waitUntilScreenReady()
+          .removeSchema();
+      schemaRegistryList
+          .waitUntilScreenReady();
+      Assertions.assertFalse(schemaRegistryList.isSchemaVisible(AVRO_API.getName()),"isSchemaVisible()");
+      SCHEMA_LIST.remove(AVRO_API);
     }
 
     @DisplayName("should create JSON schema")
@@ -129,7 +156,7 @@ void deleteSchemaAvro() {
     @AutomationStatus(status = Status.AUTOMATED)
     @CaseId(89)
     @Test
-    @Order(4)
+    @Order(5)
     void createSchemaJson() {
         Schema schemaJson = Schema.createSchemaJson();
         naviSideBar
@@ -162,7 +189,7 @@ void createSchemaJson() {
     @AutomationStatus(status = Status.AUTOMATED)
     @CaseId(189)
     @Test
-    @Order(5)
+    @Order(6)
     void deleteSchemaJson() {
         naviSideBar
                 .openSideMenu(SCHEMA_REGISTRY);
@@ -183,7 +210,7 @@ void deleteSchemaJson() {
     @AutomationStatus(status = Status.AUTOMATED)
     @CaseId(91)
     @Test
-    @Order(6)
+    @Order(7)
     void createSchemaProtobuf() {
         Schema schemaProtobuf = Schema.createSchemaProtobuf();
         naviSideBar
@@ -216,7 +243,7 @@ void createSchemaProtobuf() {
     @AutomationStatus(status = Status.AUTOMATED)
     @CaseId(223)
     @Test
-    @Order(7)
+    @Order(8)
     void deleteSchemaProtobuf() {
         naviSideBar
                 .openSideMenu(SCHEMA_REGISTRY);