Issue/refactoring of smoke test (#2851)

* Deleted methods like screenShooter from BaseTest

* Added TopPanel object class in Facade

* Added List of SideMenuOptions

* Deleted Screenshooter.java

* Deleted NoReferenceScreenshotFoundException.java

* Add methods in TopPanel

* Refactored SmokeTests class

* Refactored SmokeTests class

* Refactored SmokeTests class

* Resolve conversation

* Reformat discordBtn locator

Co-authored-by: Vlad Senyuta <66071557+VladSenyuta@users.noreply.github.com>
This commit is contained in:
Alexandr Nezboretskiy 2022-11-01 15:10:16 +02:00 committed by GitHub
parent cd2d8b026f
commit ee920b43c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 192 deletions

View file

@ -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<SelenideElement> getAllMenuButtons() {
expandCluster(CLUSTER_NAME);
return Stream.of(SideMenuOption.values())
.map(option -> $x(String.format(sideMenuOptionElementLocator, option.value)))
.collect(Collectors.toList());
}
}

View file

@ -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<SelenideElement> getAllVisibleElements() {
return Arrays.asList(kafkaLogo, kafkaVersion, logOutBtn, gitBtn, discordBtn);
}
public List<SelenideElement> getAllEnabledElements() {
return Arrays.asList(logOutBtn, gitBtn, discordBtn, kafkaLogo);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}
}

View file

@ -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");
}

View file

@ -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();
}