diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/NaviSideBar.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/NaviSideBar.java index 4e6bab8eb0..0f6f4c2260 100644 --- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/NaviSideBar.java +++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/NaviSideBar.java @@ -5,6 +5,9 @@ import com.codeborne.selenide.SelenideElement; import io.qameta.allure.Step; import java.time.Duration; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.codeborne.selenide.Selenide.$x; import static com.provectus.kafka.ui.settings.Source.CLUSTER_NAME; @@ -16,6 +19,14 @@ public class NaviSideBar { protected String sideMenuOptionElementLocator = ".//ul/li[contains(.,'%s')]"; protected String clusterElementLocator = "//aside/ul/li[contains(.,'%s')]"; + private SelenideElement expandCluster(String clusterName) { + SelenideElement clusterElement = $x(String.format(clusterElementLocator, clusterName)).shouldBe(Condition.visible); + if (clusterElement.parent().$$x(".//ul").size() == 0) { + clusterElement.click(); + } + return clusterElement; + } + @Step public NaviSideBar waitUntilScreenReady() { loadingSpinner.shouldBe(Condition.disappear, Duration.ofSeconds(30)); @@ -25,11 +36,7 @@ public class NaviSideBar { @Step public NaviSideBar openSideMenu(String clusterName, SideMenuOption option) { - SelenideElement clusterElement = $x(String.format(clusterElementLocator, clusterName)).shouldBe(Condition.visible); - if (clusterElement.parent().$$x(".//ul").size() == 0) { - clusterElement.click(); - } - clusterElement + expandCluster(clusterName) .parent() .$x(String.format(sideMenuOptionElementLocator, option.value)) .click(); @@ -43,6 +50,7 @@ public class NaviSideBar { } public enum SideMenuOption { + DASHBOARD("Dashboard"), BROKERS("Brokers"), TOPICS("Topics"), CONSUMERS("Consumers"), @@ -56,4 +64,11 @@ public class NaviSideBar { this.value = value; } } + + public List getAllMenuButtons() { + expandCluster(CLUSTER_NAME); + return Stream.of(SideMenuOption.values()) + .map(option -> $x(String.format(sideMenuOptionElementLocator, option.value))) + .collect(Collectors.toList()); + } } \ No newline at end of file diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/TopPanel.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/TopPanel.java new file mode 100644 index 0000000000..8101543abf --- /dev/null +++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/TopPanel.java @@ -0,0 +1,24 @@ +package com.provectus.kafka.ui.pages; + +import com.codeborne.selenide.SelenideElement; + +import java.util.Arrays; +import java.util.List; + +import static com.codeborne.selenide.Selenide.$x; + +public class TopPanel { + protected SelenideElement kafkaLogo = $x("//a[contains(text(),'UI for Apache Kafka')]"); + protected SelenideElement kafkaVersion = $x("//a[@title='Current commit']"); + protected SelenideElement logOutBtn = $x("//button[contains(text(),'Log out')]"); + protected SelenideElement gitBtn = $x("//a[@href='https://github.com/provectus/kafka-ui']"); + protected SelenideElement discordBtn = $x("//a[contains(@href,'https://discord.com/invite')]"); + + public List getAllVisibleElements() { + return Arrays.asList(kafkaLogo, kafkaVersion, logOutBtn, gitBtn, discordBtn); + } + + public List getAllEnabledElements() { + return Arrays.asList(logOutBtn, gitBtn, discordBtn, kafkaLogo); + } +} diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/screenshots/NoReferenceScreenshotFoundException.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/screenshots/NoReferenceScreenshotFoundException.java deleted file mode 100644 index 0011c4f0a1..0000000000 --- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/screenshots/NoReferenceScreenshotFoundException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.provectus.kafka.ui.utilities.screenshots; - -public class NoReferenceScreenshotFoundException extends Throwable { - public NoReferenceScreenshotFoundException(String name) { - super("no reference screenshot found for " + name); - } -} diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/screenshots/Screenshooter.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/screenshots/Screenshooter.java deleted file mode 100644 index 136a9e8bd4..0000000000 --- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/utilities/screenshots/Screenshooter.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.provectus.kafka.ui.utilities.screenshots; - -import io.qameta.allure.Allure; -import io.qameta.allure.Attachment; -import lombok.SneakyThrows; -import org.junit.jupiter.api.Assertions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import ru.yandex.qatools.ashot.AShot; -import ru.yandex.qatools.ashot.Screenshot; -import ru.yandex.qatools.ashot.comparison.ImageDiff; -import ru.yandex.qatools.ashot.comparison.ImageDiffer; -import ru.yandex.qatools.ashot.coordinates.WebDriverCoordsProvider; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.util.List; - -import static com.codeborne.selenide.WebDriverRunner.getWebDriver; - -public class Screenshooter { - - public static Logger log = LoggerFactory.getLogger(Screenshooter.class); - - private static final int PIXELS_THRESHOLD = - Integer.parseInt(System.getProperty("PIXELS_THRESHOLD", "200")); - private static final String SCREENSHOTS_FOLDER = - System.getProperty("SCREENSHOTS_FOLDER", "com/provectus/kafka/ui/utilities/screenshots/"); - private static final String DIFF_SCREENSHOTS_FOLDER = - System.getProperty("DIFF_SCREENSHOTS_FOLDER", "build/__diff__/"); - private static final String ACTUAL_SCREENSHOTS_FOLDER = - System.getProperty("ACTUAL_SCREENSHOTS_FOLDER", "build/__actual__/"); - private static final boolean SHOULD_SAVE_SCREENSHOTS_IF_NOT_EXIST = - Boolean.parseBoolean(System.getProperty("SHOULD_SAVE_SCREENSHOTS_IF_NOT_EXIST", "true")); - private static final boolean TURN_OFF_SCREENSHOTS = - Boolean.parseBoolean(System.getProperty("TURN_OFF_SCREENSHOTS", "false")); - private static final boolean USE_LOCAL_BROWSER = - Boolean.parseBoolean(System.getProperty("USE_LOCAL_BROWSER", "false")); - - private File newFile(String name) { - var file = new File(name); - if (!file.exists()) { - file.mkdirs(); - } - return file; - } - - public Screenshooter() { - List.of(SCREENSHOTS_FOLDER, DIFF_SCREENSHOTS_FOLDER, ACTUAL_SCREENSHOTS_FOLDER) - .forEach(this::newFile); - } - - public void compareScreenshots(String name) { - compareScreenshots(name, false); - } - - - public void compareScreenshots(String name, boolean shouldUpdateScreenshotIfDiffer) { - if (TURN_OFF_SCREENSHOTS || USE_LOCAL_BROWSER) { - log.warn(String.format("compareScreenshots turned off due TURN_OFF_SCREENSHOTS || USE_LOCAL_BROWSER: %b || %b" - , TURN_OFF_SCREENSHOTS, USE_LOCAL_BROWSER)); - return; - } - if (!doesScreenshotExist(name)) { - if (SHOULD_SAVE_SCREENSHOTS_IF_NOT_EXIST) { - updateActualScreenshot(name); - } else { - try { - throw new NoReferenceScreenshotFoundException(name); - } catch (NoReferenceScreenshotFoundException e) { - e.printStackTrace(); - } - } - } else { - makeImageDiff(name, shouldUpdateScreenshotIfDiffer); - } - } - - - private void updateActualScreenshot(String name) { - Screenshot actual = - new AShot().coordsProvider(new WebDriverCoordsProvider()).takeScreenshot(getWebDriver()); - File file = newFile(SCREENSHOTS_FOLDER + name + ".png"); - try { - ImageIO.write(actual.getImage(), "png", file); - } catch (IOException e) { - e.printStackTrace(); - } - log.debug(String.format("created screenshot: %s \n at %s", name, file.getAbsolutePath())); - } - - private static boolean doesScreenshotExist(String name) { - return new File(SCREENSHOTS_FOLDER + name + ".png").exists(); - } - - @SneakyThrows - private void makeImageDiff(String expectedName, boolean shouldUpdateScreenshotIfDiffer) { - String fullPathNameExpected = SCREENSHOTS_FOLDER + expectedName + ".png"; - String fullPathNameActual = ACTUAL_SCREENSHOTS_FOLDER + expectedName + ".png"; - String fullPathNameDiff = DIFF_SCREENSHOTS_FOLDER + expectedName + ".png"; - - // activating allure plugin for showing diffs in report - Allure.label("testType", "screenshotDiff"); - - Screenshot actual = - new AShot().coordsProvider(new WebDriverCoordsProvider()).takeScreenshot(getWebDriver()); - ImageIO.write(actual.getImage(), "png", newFile(fullPathNameActual)); - - Screenshot expected = new Screenshot(ImageIO.read(newFile(fullPathNameExpected))); - ImageDiff diff = new ImageDiffer().makeDiff(actual, expected); - BufferedImage diffImage = diff.getMarkedImage(); - ImageIO.write(diffImage, "png", newFile(fullPathNameDiff)); - // adding to report - diff(fullPathNameDiff); - // adding to report - actual(fullPathNameActual); - // adding to report - expected(fullPathNameExpected); - - if (shouldUpdateScreenshotIfDiffer) { - if (diff.getDiffSize() > PIXELS_THRESHOLD) { - updateActualScreenshot(expectedName); - } - } else { - Assertions.assertTrue( - PIXELS_THRESHOLD >= diff.getDiffSize(), - String.format("Amount of differing pixels should be less or equals than %s, actual %s\n" + - "diff file: %s", - PIXELS_THRESHOLD, diff.getDiffSize(), FileSystems.getDefault().getPath(fullPathNameDiff).normalize().toAbsolutePath())); - } - } - - @SneakyThrows - private byte[] imgToBytes(String filename) { - BufferedImage bImage2 = ImageIO.read(new File(filename)); - var bos2 = new ByteArrayOutputStream(); - ImageIO.write(bImage2, "png", bos2); - return bos2.toByteArray(); - } - - - @Attachment - private byte[] actual(String actualFileName) { - return imgToBytes(actualFileName); - } - - - @Attachment - private byte[] expected(String expectedFileName) { - return imgToBytes(expectedFileName); - } - - - @Attachment - private byte[] diff(String diffFileName) { - return imgToBytes(diffFileName); - } -} diff --git a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/SmokeTests.java b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/SmokeTests.java index e876d3a634..e1e6927c43 100644 --- a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/SmokeTests.java +++ b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/SmokeTests.java @@ -1,10 +1,11 @@ package com.provectus.kafka.ui; +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.enums.Status; import io.qase.api.annotation.CaseId; -import org.junit.jupiter.api.DisplayName; +import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.Test; public class SmokeTests extends BaseTest { @@ -12,8 +13,20 @@ public class SmokeTests extends BaseTest { @Test @AutomationStatus(status = Status.AUTOMATED) @CaseId(198) - @DisplayName("main page should load") - void mainPageLoads() { - compareScreenshots("main"); + public void checkBasePageElements(){ + SoftAssertions softly = new SoftAssertions(); + topPanel.getAllVisibleElements() + .forEach(element -> + softly.assertThat(element.is(Condition.visible)) + .as(element.getSearchCriteria() + " isVisible()").isTrue()); + topPanel.getAllEnabledElements() + .forEach(element -> + softly.assertThat(element.is(Condition.enabled)) + .as(element.getSearchCriteria() + " isEnabled()").isTrue()); + naviSideBar.getAllMenuButtons() + .forEach(element -> + softly.assertThat(element.is(Condition.enabled) && element.is(Condition.visible)) + .as(element.getSearchCriteria() + " isEnabled()").isTrue()); + softly.assertAll(); } -} +} \ No newline at end of file diff --git a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/BaseTest.java b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/BaseTest.java index a3086fd715..11cf07c622 100644 --- a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/BaseTest.java +++ b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/base/BaseTest.java @@ -1,11 +1,9 @@ package com.provectus.kafka.ui.base; -import com.codeborne.selenide.Condition; import com.codeborne.selenide.Selenide; import com.codeborne.selenide.WebDriverRunner; import com.provectus.kafka.ui.utilities.qaseIoUtils.DisplayNameGenerator; import com.provectus.kafka.ui.utilities.qaseIoUtils.TestCaseGenerator; -import com.provectus.kafka.ui.utilities.screenshots.Screenshooter; import io.github.cdimascio.dotenv.Dotenv; import io.qameta.allure.Allure; import lombok.extern.slf4j.Slf4j; @@ -24,7 +22,6 @@ import org.testcontainers.utility.DockerImageName; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.time.Duration; import static com.provectus.kafka.ui.base.Setup.*; import static com.provectus.kafka.ui.settings.Source.BASE_WEB_URL; @@ -35,18 +32,8 @@ public class BaseTest extends Facade { private static final String SELENIUM_IMAGE_NAME = "selenium/standalone-chrome:103.0"; private static final String SELENIARM_STANDALONE_CHROMIUM = "seleniarm/standalone-chromium:103.0"; - private final Screenshooter screenshooter = new Screenshooter(); - protected static BrowserWebDriverContainer webDriverContainer = null; - public void compareScreenshots(String name) { - screenshooter.compareScreenshots(name); - } - - public void compareScreenshots(String name, Boolean shouldUpdateScreenshots) { - screenshooter.compareScreenshots(name, shouldUpdateScreenshots); - } - private static boolean isARM64() { return System.getProperty("os.arch").equals("aarch64"); } 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 ac223c62b1..5b9533c30e 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 @@ -2,6 +2,7 @@ package com.provectus.kafka.ui.base; 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.connector.ConnectorCreateForm; import com.provectus.kafka.ui.pages.connector.ConnectorDetails; import com.provectus.kafka.ui.pages.connector.KafkaConnectList; @@ -30,4 +31,5 @@ public abstract class Facade { protected ConsumersDetails consumersDetails = new ConsumersDetails(); protected ConsumersList consumersList = new ConsumersList(); protected NaviSideBar naviSideBar = new NaviSideBar(); + protected TopPanel topPanel = new TopPanel(); }