Merge branch 'master' into partitions_reassignment

This commit is contained in:
Ilya Kuramshin 2022-11-23 23:51:36 +04:00 committed by GitHub
commit 5255e05357
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 473 additions and 381 deletions

View file

@ -2,6 +2,6 @@ apiVersion: v2
name: kafka-ui
description: A Helm chart for kafka-UI
type: application
version: 0.4.5
version: 0.4.6
appVersion: v0.4.0
icon: https://github.com/provectus/kafka-ui/raw/master/documentation/images/kafka-ui-logo.png

View file

@ -87,6 +87,9 @@ spec:
{{- $contextPath := .Values.envs.config.SERVER_SERVLET_CONTEXT_PATH | default "" | printf "%s/actuator/health" | urlParse }}
path: {{ get $contextPath "path" }}
port: http
{{- if .Values.probes.useHttpsScheme }}
scheme: HTTPS
{{- end }}
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
@ -95,6 +98,9 @@ spec:
{{- $contextPath := .Values.envs.config.SERVER_SERVLET_CONTEXT_PATH | default "" | printf "%s/actuator/health" | urlParse }}
path: {{ get $contextPath "path" }}
port: http
{{- if .Values.probes.useHttpsScheme }}
scheme: HTTPS
{{- end }}
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10

View file

@ -73,6 +73,11 @@ podLabels: {}
##
annotations: {}
## Set field schema as HTTPS for readines and liveness probe
##
probes:
useHttpsScheme: false
podSecurityContext:
{}
# fsGroup: 2000

View file

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

View file

@ -26,13 +26,13 @@ public class BrokersDetails extends BasePage {
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());
}

View file

@ -5,12 +5,9 @@ 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 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')]");

View file

@ -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.CompatibilityLevel;
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 class SchemaCreateForm extends BasePage {
@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 class SchemaCreateForm extends BasePage {
@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();

View file

@ -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 class SchemaDetails extends BasePage {
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 class SchemaDetails extends BasePage {
return this;
}
@Step
public SchemaDetails openCompareVersionMenu(){
compareVersionBtn.shouldBe(Condition.enabled).click();
return this;
}
@Step
public SchemaDetails removeSchema() {
clickByJavaScript(dotMenuBtn);

View file

@ -10,20 +10,26 @@ import com.codeborne.selenide.Condition;
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')]"));
protected SelenideElement messageAmountCell = $x("//tbody/tr/td[5]");
protected SelenideElement overviewTab = $x("//a[contains(text(),'Overview')]");
protected SelenideElement messagesTab = $x("//a[contains(text(),'Messages')]");
protected SelenideElement addFiltersBtn = $x("//button[text()='Add Filters']");
protected SelenideElement savedFiltersField = $x("//div[text()='Saved Filters']");
protected SelenideElement addFilterCodeModalTitle = $x("//label[text()='Filter code']");
protected SelenideElement addFilterCodeInput = $x("//div[@id='ace-editor']//textarea");
protected SelenideElement saveThisFilterCheckBoxAddFilterMdl = $x("//input[@name='saveFilter']");
protected SelenideElement displayNameInputAddFilterMdl = $x("//input[@placeholder='Enter Name']");
protected SelenideElement cancelBtnAddFilterMdl = $x("//button[text()='Cancel']");
protected SelenideElement addFilterBtnAddFilterMdl = $x("//button[text()='Add filter']");
protected SelenideElement editSettingsMenu = $x("//li[@role][contains(text(),'Edit settings')]");
protected SelenideElement removeTopicBtn = $x("//ul[@role='menu']//div[contains(text(),'Remove Topic')]");
protected SelenideElement confirmBtn = $x("//div[@role='dialog']//button[contains(text(),'Confirm')]");
@ -34,6 +40,7 @@ public class TopicDetails extends BasePage {
protected ElementsCollection messageGridItems = $$x("//tbody//tr");
protected String consumerIdLocator = "//a[@title='%s']";
protected String topicHeaderLocator = "//h1[contains(text(),'%s')]";
protected String filterNameLocator = "//*[@data-testid='activeSmartFilter']";
@Step
public TopicDetails waitUntilScreenReady() {
@ -106,6 +113,58 @@ public class TopicDetails extends BasePage {
return this;
}
@Step
public TopicDetails clickMessagesAddFiltersBtn() {
addFiltersBtn.shouldBe(Condition.enabled).click();
return this;
}
@Step
public TopicDetails waitUntilAddFiltersMdlVisible() {
addFilterCodeModalTitle.shouldBe(Condition.visible);
return this;
}
@Step
public TopicDetails clickAddFilterBtnAddFilterMdl() {
addFilterBtnAddFilterMdl.shouldBe(Condition.enabled).click();
addFilterCodeModalTitle.shouldBe(Condition.hidden);
return this;
}
@Step
public TopicDetails setFilterCodeFieldAddFilterMdl(String filterCode) {
addFilterCodeInput.shouldBe(Condition.enabled).sendKeys(filterCode);
return this;
}
@Step
public boolean isSaveThisFilterCheckBoxSelected() {
return isSelected(saveThisFilterCheckBoxAddFilterMdl);
}
@Step
public boolean isAddFilterBtnAddFilterMdlEnabled() {
return isEnabled(addFilterBtnAddFilterMdl);
}
@Step
public String getFilterName() {
return $x(filterNameLocator).getText();
}
public List<SelenideElement> getAllAddFilterModalVisibleElements() {
return Arrays.asList(savedFiltersField, displayNameInputAddFilterMdl, addFilterBtnAddFilterMdl, cancelBtnAddFilterMdl);
}
public List<SelenideElement> getAllAddFilterModalEnabledElements() {
return Arrays.asList(displayNameInputAddFilterMdl, cancelBtnAddFilterMdl);
}
public List<SelenideElement> getAllAddFilterModalDisabledElements() {
return Arrays.asList(addFilterBtnAddFilterMdl);
}
@Step
public TopicDetails openConsumerGroup(String consumerId) {
$x(String.format(consumerIdLocator, consumerId)).click();
@ -146,6 +205,23 @@ public class TopicDetails extends BasePage {
return getMessage(nextInt(initItems().size() - 1));
}
public enum TopicMenu {
OVERVIEW("Overview"),
MESSAGES("Messages"),
CONSUMERS("Consumers"),
SETTINGS("Settings");
private final String value;
TopicMenu(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
public static class MessageGridItem extends BasePage {
private final SelenideElement element;
@ -211,21 +287,4 @@ public class TopicDetails extends BasePage {
return this;
}
}
public enum TopicMenu {
OVERVIEW("Overview"),
MESSAGES("Messages"),
CONSUMERS("Consumers"),
SETTINGS("Settings");
private final String value;
TopicMenu(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
}

View file

@ -5,19 +5,16 @@ 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 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("//h1[text()='Topics']");
protected SelenideElement topicListHeader = $x("//*[text()='Topics']");
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']");
@ -56,13 +53,13 @@ public class TopicsList extends BasePage {
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());
}

View file

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

View file

@ -57,4 +57,16 @@ public class WebUtils {
}
return isEnabled;
}
public static boolean isSelected(SelenideElement element) {
log.debug("\nisSelected: {}", element.getSearchCriteria());
boolean isSelected = false;
try {
element.shouldBe(Condition.selected);
isSelected = true;
} catch (Throwable e) {
log.debug("{} is not selected", element.getSearchCriteria());
}
return isSelected;
}
}

View file

@ -103,25 +103,52 @@ public class SchemasTests extends BaseTest {
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 @@ public class SchemasTests extends BaseTest {
@AutomationStatus(status = Status.AUTOMATED)
@CaseId(89)
@Test
@Order(4)
@Order(5)
void createSchemaJson() {
Schema schemaJson = Schema.createSchemaJson();
naviSideBar
@ -162,7 +189,7 @@ public class SchemasTests extends BaseTest {
@AutomationStatus(status = Status.AUTOMATED)
@CaseId(189)
@Test
@Order(5)
@Order(6)
void deleteSchemaJson() {
naviSideBar
.openSideMenu(SCHEMA_REGISTRY);
@ -183,7 +210,7 @@ public class SchemasTests extends BaseTest {
@AutomationStatus(status = Status.AUTOMATED)
@CaseId(91)
@Test
@Order(6)
@Order(7)
void createSchemaProtobuf() {
Schema schemaProtobuf = Schema.createSchemaProtobuf();
naviSideBar
@ -216,7 +243,7 @@ public class SchemasTests extends BaseTest {
@AutomationStatus(status = Status.AUTOMATED)
@CaseId(223)
@Test
@Order(7)
@Order(8)
void deleteSchemaProtobuf() {
naviSideBar
.openSideMenu(SCHEMA_REGISTRY);

View file

@ -31,11 +31,11 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TopicActionsTests extends BaseTest {
public class TopicsTests extends BaseTest {
private static final long SUITE_ID = 2;
private static final String SUITE_TITLE = "Topics";
private static final Topic TOPIC_TO_CREATE = new Topic()
.setName("new-topic-"+ randomAlphabetic(5))
.setName("new-topic-" + randomAlphabetic(5))
.setPartitions("1")
.setCustomParameterType(COMPRESSION_TYPE)
.setCustomParameterValue("producer")
@ -83,8 +83,10 @@ public class TopicActionsTests extends BaseTest {
.waitUntilScreenReady()
.openTopic(TOPIC_TO_CREATE.getName());
SoftAssertions softly = new SoftAssertions();
softly.assertThat(topicDetails.isTopicHeaderVisible(TOPIC_TO_CREATE.getName())).as("isTopicHeaderVisible()").isTrue();
softly.assertThat(topicDetails.getCleanUpPolicy()).as("getCleanUpPolicy()").isEqualTo(TOPIC_TO_CREATE.getCleanupPolicyValue().toString());
softly.assertThat(topicDetails.isTopicHeaderVisible(TOPIC_TO_CREATE.getName())).as("isTopicHeaderVisible()")
.isTrue();
softly.assertThat(topicDetails.getCleanUpPolicy()).as("getCleanUpPolicy()")
.isEqualTo(TOPIC_TO_CREATE.getCleanupPolicyValue().toString());
softly.assertThat(topicDetails.getPartitions()).as("getPartitions()").isEqualTo(TOPIC_TO_CREATE.getPartitions());
softly.assertAll();
naviSideBar
@ -132,10 +134,14 @@ public class TopicActionsTests extends BaseTest {
.openDotMenu()
.clickEditSettingsMenu();
SoftAssertions softly = new SoftAssertions();
softly.assertThat(topicCreateEditForm.getCleanupPolicy()).as("getCleanupPolicy()").isEqualTo(TOPIC_FOR_UPDATE.getCleanupPolicyValue().getVisibleText());
softly.assertThat(topicCreateEditForm.getTimeToRetain()).as("getTimeToRetain()").isEqualTo(TOPIC_FOR_UPDATE.getTimeToRetainData());
softly.assertThat(topicCreateEditForm.getMaxSizeOnDisk()).as("getMaxSizeOnDisk()").isEqualTo(TOPIC_FOR_UPDATE.getMaxSizeOnDisk().getVisibleText());
softly.assertThat(topicCreateEditForm.getMaxMessageBytes()).as("getMaxMessageBytes()").isEqualTo(TOPIC_FOR_UPDATE.getMaxMessageBytes());
softly.assertThat(topicCreateEditForm.getCleanupPolicy()).as("getCleanupPolicy()")
.isEqualTo(TOPIC_FOR_UPDATE.getCleanupPolicyValue().getVisibleText());
softly.assertThat(topicCreateEditForm.getTimeToRetain()).as("getTimeToRetain()")
.isEqualTo(TOPIC_FOR_UPDATE.getTimeToRetainData());
softly.assertThat(topicCreateEditForm.getMaxSizeOnDisk()).as("getMaxSizeOnDisk()")
.isEqualTo(TOPIC_FOR_UPDATE.getMaxSizeOnDisk().getVisibleText());
softly.assertThat(topicCreateEditForm.getMaxMessageBytes()).as("getMaxMessageBytes()")
.isEqualTo(TOPIC_FOR_UPDATE.getMaxMessageBytes());
softly.assertAll();
}
@ -237,7 +243,7 @@ public class TopicActionsTests extends BaseTest {
@AutomationStatus(status = Status.AUTOMATED)
@CaseId(2)
@Test
void checkTopicListElements(){
void checkTopicListElements() {
naviSideBar
.openSideMenu(TOPICS);
topicsList
@ -252,6 +258,45 @@ public class TopicActionsTests extends BaseTest {
softly.assertAll();
}
@DisplayName("Filter adding within Topic")
@Suite(suiteId = SUITE_ID, title = SUITE_TITLE)
@AutomationStatus(status = Status.AUTOMATED)
@CaseId(12)
@Test
void addingNewFilterWithinTopic() {
String topicName = "_schemas";
String filterName = "123ABC";
naviSideBar
.openSideMenu(TOPICS);
topicsList
.waitUntilScreenReady()
.openTopic(topicName);
topicDetails
.openDetailsTab(TopicDetails.TopicMenu.MESSAGES)
.clickMessagesAddFiltersBtn()
.waitUntilAddFiltersMdlVisible();
SoftAssertions softly = new SoftAssertions();
topicDetails.getAllAddFilterModalVisibleElements().forEach(element ->
softly.assertThat(element.is(Condition.visible))
.as(element.getSearchCriteria() + " isVisible()").isTrue());
topicDetails.getAllAddFilterModalEnabledElements().forEach(element ->
softly.assertThat(element.is(Condition.enabled))
.as(element.getSearchCriteria() + " isEnabled()").isTrue());
topicDetails.getAllAddFilterModalDisabledElements().forEach(element ->
softly.assertThat(element.is(Condition.enabled))
.as(element.getSearchCriteria() + " isEnabled()").isFalse());
softly.assertThat(topicDetails.isSaveThisFilterCheckBoxSelected()).as("isSaveThisFilterCheckBoxSelected()")
.isFalse();
softly.assertAll();
topicDetails
.setFilterCodeFieldAddFilterMdl(filterName);
assertThat(topicDetails.isAddFilterBtnAddFilterMdlEnabled()).as("isMessagesAddFilterTabAddFilterBtnEnabled()")
.isTrue();
topicDetails.clickAddFilterBtnAddFilterMdl();
assertThat(topicDetails.getFilterName()).as("isFilterNameVisible(filterName)")
.isEqualTo(filterName);
}
@AfterAll
public void afterAll() {
TOPIC_LIST.forEach(topic -> apiHelper.deleteTopic(CLUSTER_NAME, topic.getName()));

View file

@ -2,7 +2,7 @@ import React from 'react';
import New from 'components/Schemas/New/New';
import { render, WithRoute } from 'lib/testHelpers';
import { clusterSchemaNewPath } from 'lib/paths';
import { act, screen } from '@testing-library/react';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
const clusterName = 'local';
@ -10,15 +10,17 @@ const subjectValue = 'subject';
const schemaValue = 'schema';
describe('New Component', () => {
beforeEach(async () => {
await render(
<WithRoute path={clusterSchemaNewPath()}>
<New />
</WithRoute>,
{
initialEntries: [clusterSchemaNewPath(clusterName)],
}
);
beforeEach(() => {
waitFor(() => {
render(
<WithRoute path={clusterSchemaNewPath()}>
<New />
</WithRoute>,
{
initialEntries: [clusterSchemaNewPath(clusterName)],
}
);
});
});
it('renders component', () => {
@ -33,15 +35,9 @@ describe('New Component', () => {
const schema = screen.getAllByRole('textbox')[1];
const schemaTypeSelect = screen.getByRole('listbox');
await act(async () => {
await userEvent.type(subject, subjectValue);
});
await act(async () => {
await userEvent.type(schema, schemaValue);
});
await act(async () => {
await userEvent.selectOptions(schemaTypeSelect, ['AVRO']);
});
await userEvent.type(subject, subjectValue);
await userEvent.type(schema, schemaValue);
await userEvent.selectOptions(schemaTypeSelect, ['AVRO']);
const submitBtn = screen.getByRole('button', { name: /Submit/i });
expect(submitBtn).toBeEnabled();

View file

@ -11,8 +11,8 @@ const clusterName = 'test-cluster';
jest.mock('components/Topics/List/TopicTable', () => () => <>TopicTableMock</>);
describe('ListPage Component', () => {
const renderComponent = () => {
return render(
const renderComponent = () =>
render(
<ClusterContext.Provider
value={{
isReadOnly: false,
@ -27,7 +27,6 @@ describe('ListPage Component', () => {
</ClusterContext.Provider>,
{ initialEntries: [clusterTopicsPath(clusterName)] }
);
};
beforeEach(() => {
renderComponent();

View file

@ -1,6 +1,6 @@
import React from 'react';
import { render, WithRoute } from 'lib/testHelpers';
import { act, screen, waitFor, within } from '@testing-library/react';
import { screen, within } from '@testing-library/react';
import { CleanUpPolicy, TopicsResponse } from 'generated-sources';
import { externalTopicPayload, topicsPayload } from 'lib/fixtures/topics';
import ClusterContext from 'components/contexts/ClusterContext';
@ -156,7 +156,7 @@ describe('TopicTable Components', () => {
});
it('handels delete button click', async () => {
const button = getButtonByName('Delete selected topics');
await act(() => userEvent.click(button));
await userEvent.click(button);
expect(
screen.getByText(
'Are you sure you want to remove selected topics?'
@ -165,14 +165,14 @@ describe('TopicTable Components', () => {
const confirmBtn = getButtonByName('Confirm');
expect(confirmBtn).toBeInTheDocument();
expect(deleteTopicMock).not.toHaveBeenCalled();
await act(() => userEvent.click(confirmBtn));
await userEvent.click(confirmBtn);
expect(deleteTopicMock).toHaveBeenCalledTimes(2);
expect(screen.getAllByRole('checkbox')[1]).not.toBeChecked();
expect(screen.getAllByRole('checkbox')[2]).not.toBeChecked();
});
it('handels purge messages button click', async () => {
const button = getButtonByName('Purge messages of selected topics');
await act(() => userEvent.click(button));
await userEvent.click(button);
expect(
screen.getByText(
'Are you sure you want to purge messages of selected topics?'
@ -181,7 +181,7 @@ describe('TopicTable Components', () => {
const confirmBtn = getButtonByName('Confirm');
expect(confirmBtn).toBeInTheDocument();
expect(mockUnwrap).not.toHaveBeenCalled();
await act(() => userEvent.click(confirmBtn));
await userEvent.click(confirmBtn);
expect(mockUnwrap).toHaveBeenCalledTimes(2);
expect(screen.getAllByRole('checkbox')[1]).not.toBeChecked();
expect(screen.getAllByRole('checkbox')[2]).not.toBeChecked();
@ -205,7 +205,7 @@ describe('TopicTable Components', () => {
expect(btns[1]).toBeDisabled();
});
it('renders action buttons', async () => {
renderComponent({ topics: topicsPayload, pageCount: 1 });
await renderComponent({ topics: topicsPayload, pageCount: 1 });
expect(
screen.getAllByRole('button', { name: 'Dropdown Toggle' }).length
).toEqual(2);
@ -274,8 +274,8 @@ describe('TopicTable Components', () => {
expect(
screen.getByText('Are you sure want to clear topic messages?')
).toBeInTheDocument();
await act(() =>
userEvent.click(screen.getByRole('button', { name: 'Confirm' }))
await userEvent.click(
screen.getByRole('button', { name: 'Confirm' })
);
expect(mockUnwrap).toHaveBeenCalled();
});
@ -301,10 +301,10 @@ describe('TopicTable Components', () => {
await expectDropdownExists();
await userEvent.click(screen.getByText('Remove Topic'));
expect(screen.getByText('Confirm the action')).toBeInTheDocument();
await waitFor(() =>
userEvent.click(screen.getByRole('button', { name: 'Confirm' }))
await userEvent.click(
screen.getByRole('button', { name: 'Confirm' })
);
await waitFor(() => expect(deleteTopicMock).toHaveBeenCalled());
expect(deleteTopicMock).toHaveBeenCalled();
});
});
describe('and recreate topic action', () => {
@ -313,10 +313,10 @@ describe('TopicTable Components', () => {
await expectDropdownExists();
await userEvent.click(screen.getByText('Recreate Topic'));
expect(screen.getByText('Confirm the action')).toBeInTheDocument();
await waitFor(() =>
userEvent.click(screen.getByRole('button', { name: 'Confirm' }))
await userEvent.click(
screen.getByRole('button', { name: 'Confirm' })
);
await waitFor(() => expect(recreateTopicMock).toHaveBeenCalled());
expect(recreateTopicMock).toHaveBeenCalled();
});
});
});

View file

@ -24,7 +24,7 @@ jest.mock('lib/hooks/api/topics', () => ({
useCreateTopic: jest.fn(),
}));
const renderComponent = (path: string) => {
const renderComponent = (path: string) =>
render(
<Routes>
<Route path={clusterTopicNewPath()} element={<New />} />
@ -33,7 +33,7 @@ const renderComponent = (path: string) => {
</Routes>,
{ initialEntries: [path] }
);
};
const createTopicMock = jest.fn();
describe('New', () => {
@ -47,28 +47,21 @@ describe('New', () => {
});
it('checks header for create new', async () => {
await act(() => renderComponent(clusterTopicNewPath(clusterName)));
await act(() => {
renderComponent(clusterTopicNewPath(clusterName));
});
expect(screen.getByRole('heading', { name: 'Create' })).toBeInTheDocument();
});
it('checks header for copy', async () => {
await act(() =>
renderComponent(`${clusterTopicCopyPath(clusterName)}?name=test`)
);
it('checks header for copy', () => {
renderComponent(`${clusterTopicCopyPath(clusterName)}?name=test`);
expect(screen.getByRole('heading', { name: 'Copy' })).toBeInTheDocument();
});
it('validates form', async () => {
await act(() => renderComponent(clusterTopicNewPath(clusterName)));
await waitFor(async () => {
await userEvent.type(
screen.getByPlaceholderText('Topic Name'),
topicName
);
});
await waitFor(async () => {
await userEvent.clear(screen.getByPlaceholderText('Topic Name'));
});
renderComponent(clusterTopicNewPath(clusterName));
await userEvent.type(screen.getByPlaceholderText('Topic Name'), topicName);
await userEvent.clear(screen.getByPlaceholderText('Topic Name'));
await waitFor(() => {
expect(screen.getByText('name is a required field')).toBeInTheDocument();
});
@ -77,31 +70,21 @@ describe('New', () => {
});
it('validates form invalid name', async () => {
await act(() => renderComponent(clusterTopicNewPath(clusterName)));
await waitFor(() => {
userEvent.type(screen.getByPlaceholderText('Topic Name'), 'Invalid,Name');
});
await waitFor(() => {
expect(
screen.getByText('Only alphanumeric, _, -, and . allowed')
).toBeInTheDocument();
});
renderComponent(clusterTopicNewPath(clusterName));
await userEvent.type(
screen.getByPlaceholderText('Topic Name'),
'Invalid,Name'
);
expect(
screen.getByText('Only alphanumeric, _, -, and . allowed')
).toBeInTheDocument();
});
it('submits valid form', async () => {
await act(() => renderComponent(clusterTopicNewPath(clusterName)));
await act(async () => {
await userEvent.type(
screen.getByPlaceholderText('Topic Name'),
topicName
);
});
await act(async () => {
await userEvent.click(screen.getByText('Create topic'));
});
await waitFor(() => expect(createTopicMock).toHaveBeenCalledTimes(1));
await waitFor(() =>
expect(mockNavigate).toHaveBeenLastCalledWith(`../${topicName}`)
);
renderComponent(clusterTopicNewPath(clusterName));
await userEvent.type(screen.getByPlaceholderText('Topic Name'), topicName);
await userEvent.click(screen.getByText('Create topic'));
expect(createTopicMock).toHaveBeenCalledTimes(1);
expect(mockNavigate).toHaveBeenLastCalledWith(`../${topicName}`);
});
});

View file

@ -2,7 +2,7 @@ import React from 'react';
import DangerZone, {
DangerZoneProps,
} from 'components/Topics/Topic/Edit/DangerZone/DangerZone';
import { act, screen, waitFor, within } from '@testing-library/react';
import { screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { render, WithRoute } from 'lib/testHelpers';
import {
@ -52,7 +52,7 @@ const checkDialogThenPressCancel = async () => {
};
describe('DangerZone', () => {
it('renders the component', async () => {
it('renders the component', () => {
renderComponent();
const numberOfPartitionsEditForm = screen.getByRole('form', {
@ -98,8 +98,8 @@ describe('DangerZone', () => {
await userEvent.click(
within(numberOfPartitionsEditForm).getByRole('button')
);
await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument());
await waitFor(() => clickOnDialogSubmitButton());
expect(screen.getByRole('dialog')).toBeInTheDocument();
await clickOnDialogSubmitButton();
expect(mockIncreaseTopicPartitionsCount).toHaveBeenCalledTimes(1);
});
@ -129,12 +129,10 @@ describe('DangerZone', () => {
within(replicationFactorEditForm).getByRole('button')
);
await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument());
await waitFor(() => clickOnDialogSubmitButton());
expect(screen.getByRole('dialog')).toBeInTheDocument();
await clickOnDialogSubmitButton();
await waitFor(() => {
expect(mockUpdateTopicReplicationFactor).toHaveBeenCalledTimes(1);
});
expect(mockUpdateTopicReplicationFactor).toHaveBeenCalledTimes(1);
});
it('should view the validation error when partition value is lower than the default passed or empty', async () => {
@ -143,22 +141,20 @@ describe('DangerZone', () => {
const partitionInputSubmitBtn = screen.getAllByText(/submit/i)[0];
const value = (defaultPartitions - 4).toString();
expect(partitionInputSubmitBtn).toBeDisabled();
await act(async () => {
await userEvent.clear(partitionInput);
await userEvent.type(partitionInput, value);
});
await userEvent.clear(partitionInput);
await userEvent.type(partitionInput, value);
expect(partitionInput).toHaveValue(+value);
expect(partitionInputSubmitBtn).toBeEnabled();
await act(async () => {
await userEvent.click(partitionInputSubmitBtn);
});
await userEvent.click(partitionInputSubmitBtn);
expect(
screen.getByText(/You can only increase the number of partitions!/i)
).toBeInTheDocument();
await userEvent.clear(partitionInput);
await waitFor(() =>
expect(screen.getByText(/are required/i)).toBeInTheDocument()
);
expect(screen.getByText(/are required/i)).toBeInTheDocument();
});
it('should view the validation error when Replication Facto value is lower than the default passed or empty', async () => {
@ -167,17 +163,13 @@ describe('DangerZone', () => {
screen.getByPlaceholderText('Replication Factor');
const replicatorFactorInputSubmitBtn = screen.getAllByText(/submit/i)[1];
await waitFor(() => userEvent.clear(replicatorFactorInput));
await userEvent.clear(replicatorFactorInput);
expect(replicatorFactorInputSubmitBtn).toBeEnabled();
await userEvent.click(replicatorFactorInputSubmitBtn);
await waitFor(() =>
expect(screen.getByText(/are required/i)).toBeInTheDocument()
);
expect(screen.getByText(/are required/i)).toBeInTheDocument();
await userEvent.type(replicatorFactorInput, '1');
await waitFor(() =>
expect(screen.queryByText(/are required/i)).not.toBeInTheDocument()
);
expect(screen.queryByText(/are required/i)).not.toBeInTheDocument();
});
it('should close the partitions dialog if he cancel button is pressed', async () => {
@ -186,10 +178,8 @@ describe('DangerZone', () => {
const partitionInput = screen.getByPlaceholderText('Number of partitions');
const partitionInputSubmitBtn = screen.getAllByText(/submit/i)[0];
await act(async () => {
await userEvent.type(partitionInput, '5');
await userEvent.click(partitionInputSubmitBtn);
});
await userEvent.type(partitionInput, '5');
await userEvent.click(partitionInputSubmitBtn);
await checkDialogThenPressCancel();
});
@ -200,10 +190,8 @@ describe('DangerZone', () => {
screen.getByPlaceholderText('Replication Factor');
const replicatorFactorInputSubmitBtn = screen.getAllByText(/submit/i)[1];
await act(async () => {
await userEvent.type(replicatorFactorInput, '5');
await userEvent.click(replicatorFactorInputSubmitBtn);
});
await userEvent.type(replicatorFactorInput, '5');
await userEvent.click(replicatorFactorInputSubmitBtn);
await checkDialogThenPressCancel();
});

View file

@ -1,6 +1,6 @@
import React from 'react';
import Edit from 'components/Topics/Topic/Edit/Edit';
import { act, screen } from '@testing-library/react';
import { screen } from '@testing-library/react';
import { render, WithRoute } from 'lib/testHelpers';
import userEvent from '@testing-library/user-event';
import { clusterTopicEditPath } from 'lib/paths';
@ -39,7 +39,7 @@ const updateTopicMock = jest.fn();
const renderComponent = () => {
const path = clusterTopicEditPath(clusterName, topicName);
render(
return render(
<WithRoute path={clusterTopicEditPath()}>
<Edit />
</WithRoute>,
@ -48,7 +48,7 @@ const renderComponent = () => {
};
describe('Edit Component', () => {
beforeEach(async () => {
beforeEach(() => {
(useTopicDetails as jest.Mock).mockImplementation(() => ({
data: internalTopicPayload,
}));
@ -59,21 +59,21 @@ describe('Edit Component', () => {
isLoading: false,
mutateAsync: updateTopicMock,
}));
await act(() => renderComponent());
renderComponent();
});
it('renders DangerZone component', async () => {
it('renders DangerZone component', () => {
expect(screen.getByText(`DangerZone`)).toBeInTheDocument();
});
it('submits form correctly', async () => {
await act(() => renderComponent());
renderComponent();
const btn = screen.getAllByText(/Update topic/i)[0];
const field = screen.getByRole('spinbutton', {
name: 'Min In Sync Replicas * Min In Sync Replicas *',
});
await act(() => userEvent.type(field, '1'));
await act(() => userEvent.click(btn));
await userEvent.type(field, '1');
await userEvent.click(btn);
expect(updateTopicMock).toHaveBeenCalledTimes(1);
expect(mockNavigate).toHaveBeenCalledWith('../');
});

View file

@ -109,7 +109,11 @@ const Filters: React.FC<FiltersProps> = ({
);
const [currentSeekType, setCurrentSeekType] = React.useState<SeekType>(
(searchParams.get('seekType') as SeekType) || SeekType.OFFSET
SeekTypeOptions.find(
(ele) => ele.value === (searchParams.get('seekType') as SeekType)
) !== undefined
? (searchParams.get('seekType') as SeekType)
: SeekType.OFFSET
);
const [offset, setOffset] = React.useState<string>(
getOffsetFromSeekToParam(searchParams)

View file

@ -15,30 +15,28 @@ describe('AddEditFilterContainer component', () => {
code: 'mockCode',
};
const renderComponent = async (
const renderComponent = (
props: Partial<AddEditFilterContainerProps> = {}
) => {
await act(() => {
render(
<AddEditFilterContainer
cancelBtnHandler={jest.fn()}
submitBtnText={props.submitBtnText || defaultSubmitBtn}
{...props}
/>
);
});
return render(
<AddEditFilterContainer
cancelBtnHandler={jest.fn()}
submitBtnText={props.submitBtnText || defaultSubmitBtn}
{...props}
/>
);
};
describe('default Component Parameters', () => {
beforeEach(async () => {
await act(() => renderComponent());
});
it('should check the default Button text', () => {
it('should check the default Button text', async () => {
await act(() => {
renderComponent();
});
expect(screen.getByText(defaultSubmitBtn)).toBeInTheDocument();
});
it('should check whether the submit Button is disabled when the form is pristine and disabled if dirty', async () => {
renderComponent();
const submitButtonElem = screen.getByText(defaultSubmitBtn);
expect(submitButtonElem).toBeDisabled();
@ -60,6 +58,9 @@ describe('AddEditFilterContainer component', () => {
});
it('should view the error message after typing and clearing the input', async () => {
await act(() => {
renderComponent();
});
const inputs = screen.getAllByRole('textbox');
const user = userEvent.setup();
const textAreaElement = inputs[0] as HTMLTextAreaElement;
@ -77,12 +78,10 @@ describe('AddEditFilterContainer component', () => {
});
describe('Custom setup for the component', () => {
it('should render the input with default data if they are passed', async () => {
await act(() => {
renderComponent({
inputDisplayNameDefaultValue: mockData.name,
inputCodeDefaultValue: mockData.code,
});
it('should render the input with default data if they are passed', () => {
renderComponent({
inputDisplayNameDefaultValue: mockData.name,
inputCodeDefaultValue: mockData.code,
});
const inputs = screen.getAllByRole('textbox');
const textAreaElement = inputs[0] as HTMLTextAreaElement;
@ -93,11 +92,9 @@ describe('AddEditFilterContainer component', () => {
it('should test whether the cancel callback is being called', async () => {
const cancelCallback = jest.fn();
await act(() =>
renderComponent({
cancelBtnHandler: cancelCallback,
})
);
renderComponent({
cancelBtnHandler: cancelCallback,
});
const cancelBtnElement = screen.getByText(/cancel/i);
await userEvent.click(cancelBtnElement);
@ -106,7 +103,7 @@ describe('AddEditFilterContainer component', () => {
it('should test whether the submit Callback is being called', async () => {
const submitCallback = jest.fn();
await act(() => renderComponent({ submitCallback }));
renderComponent({ submitCallback });
const inputs = screen.getAllByRole('textbox');
@ -125,7 +122,7 @@ describe('AddEditFilterContainer component', () => {
});
it('should display the checkbox if the props is passed and initially check state', async () => {
await act(() => renderComponent({ isAdd: true }));
renderComponent({ isAdd: true });
const checkbox = screen.getByRole('checkbox');
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
@ -135,11 +132,11 @@ describe('AddEditFilterContainer component', () => {
it('should pass and render the correct button text', async () => {
const submitBtnText = 'submitBtnTextTest';
await act(() =>
await act(() => {
renderComponent({
submitBtnText,
})
);
});
});
expect(screen.getByText(submitBtnText)).toBeInTheDocument();
});
});

View file

@ -32,21 +32,22 @@ const renderComponent = (props: Partial<FilterModalProps> = {}) =>
describe('AddFilter component', () => {
describe('', () => {
beforeEach(() => {
renderComponent();
});
it('should test click on Saved Filters redirects to Saved components', async () => {
renderComponent();
await userEvent.click(screen.getByRole('savedFilterText'));
expect(screen.getByText('Saved Filters')).toBeInTheDocument();
expect(screen.getByRole('savedFilterText')).toBeInTheDocument();
});
it('info button to be in the document', () => {
it('info button to be in the document', async () => {
await act(() => {
renderComponent();
});
expect(screen.getByRole('button', { name: 'info' })).toBeInTheDocument();
});
it('renders InfoModal', async () => {
renderComponent();
await userEvent.click(screen.getByRole('button', { name: 'info' }));
expect(screen.getByRole('button', { name: 'Ok' })).toBeInTheDocument();
expect(
@ -55,19 +56,18 @@ describe('AddFilter component', () => {
});
it('should test click on return to custom filter redirects to Saved Filters', async () => {
await act(() => {
renderComponent();
});
await userEvent.click(screen.getByRole('savedFilterText'));
expect(screen.queryByText('Saved filters')).not.toBeInTheDocument();
expect(screen.getByRole('savedFilterText')).toBeInTheDocument();
});
});
describe('Add new filter', () => {
beforeEach(async () => {
renderComponent();
});
it('adding new filter', async () => {
renderComponent();
const codeValue = 'filter code';
const nameValue = 'filter name';
const textBoxes = screen.getAllByRole('textbox');
@ -79,11 +79,9 @@ describe('AddFilter component', () => {
expect(addFilterBtn).toBeDisabled();
expect(screen.getByPlaceholderText('Enter Name')).toBeInTheDocument();
await act(async () => {
codeTextBox.focus();
await userEvent.paste(codeValue);
await userEvent.type(nameTextBox, nameValue);
});
codeTextBox.focus();
await userEvent.paste(codeValue);
await userEvent.type(nameTextBox, nameValue);
expect(addFilterBtn).toBeEnabled();
expect(codeTextBox.value).toEqual(`${codeValue}\n\n`);
@ -91,6 +89,7 @@ describe('AddFilter component', () => {
});
it('should check unSaved filter without name', async () => {
renderComponent();
const codeTextBox = screen.getAllByRole(
'textbox'
)[0] as HTMLTextAreaElement;
@ -98,16 +97,16 @@ describe('AddFilter component', () => {
const addFilterBtn = screen.getByRole('button', { name: /Add filter/i });
expect(addFilterBtn).toBeDisabled();
expect(screen.getByPlaceholderText('Enter Name')).toBeInTheDocument();
await act(async () => {
codeTextBox.focus();
await userEvent.paste(code);
});
codeTextBox.focus();
await userEvent.paste(code);
await userEvent.tab();
expect(addFilterBtn).toBeEnabled();
expect(codeTextBox).toHaveValue(`${code}\n\n`);
});
it('calls editFilter when edit button is clicked in saved filters', async () => {
await act(() => {
renderComponent();
renderComponent({ isSavedFiltersOpen: true });
});
await userEvent.click(screen.getByText('Saved Filters'));
@ -132,14 +131,6 @@ describe('AddFilter component', () => {
const longCodeValue = 'a long filter code';
const nameValue = 'filter name';
beforeEach(async () => {
await renderComponent({
addFilter: addFilterMock,
activeFilterHandler: activeFilterHandlerMock,
toggleIsOpen: toggleModelMock,
});
});
afterEach(() => {
addFilterMock.mockClear();
activeFilterHandlerMock.mockClear();
@ -148,15 +139,18 @@ describe('AddFilter component', () => {
describe('OnSubmit conditions with codeValue and nameValue in fields', () => {
beforeEach(async () => {
renderComponent({
addFilter: addFilterMock,
activeFilterHandler: activeFilterHandlerMock,
toggleIsOpen: toggleModelMock,
});
const textAreaElement = screen.getAllByRole(
'textbox'
)[0] as HTMLTextAreaElement;
const input = screen.getAllByRole('textbox')[1];
await act(async () => {
textAreaElement.focus();
await userEvent.paste(codeValue);
await userEvent.type(input, nameValue);
});
textAreaElement.focus();
await userEvent.paste(codeValue);
await userEvent.type(input, nameValue);
});
it('OnSubmit condition with checkbox off functionality', async () => {
@ -166,19 +160,15 @@ describe('AddFilter component', () => {
});
expect(addFilterBtn).toBeEnabled();
await act(async () => {
await userEvent.click(addFilterBtn);
});
await userEvent.click(addFilterBtn);
expect(activeFilterHandlerMock).toHaveBeenCalled();
expect(addFilterMock).not.toHaveBeenCalled();
});
it('OnSubmit condition with checkbox on functionality', async () => {
await act(async () => {
await userEvent.click(screen.getByRole('checkbox'));
await userEvent.click(screen.getAllByRole('button')[2]);
});
await userEvent.click(screen.getByRole('checkbox'));
await userEvent.click(screen.getAllByRole('button')[2]);
expect(activeFilterHandlerMock).not.toHaveBeenCalled();
expect(addFilterMock).toHaveBeenCalled();
@ -195,15 +185,10 @@ describe('AddFilter component', () => {
name: /Add filter/i,
});
await act(async () => {
await userEvent.clear(nameTextBox);
});
await userEvent.clear(nameTextBox);
expect(nameTextBox).toHaveValue('');
await act(async () => {
await userEvent.click(addFilterBtn);
});
await userEvent.click(addFilterBtn);
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1);
expect(activeFilterHandlerMock).toHaveBeenCalledWith(
@ -215,27 +200,25 @@ describe('AddFilter component', () => {
-1
);
// get reset-ed
await userEvent.clear(codeTextBox);
expect(codeTextBox).toHaveValue(``);
expect(toggleModelMock).toHaveBeenCalled();
codeTextBox.focus();
await act(async () => {
await userEvent.paste(codeValue);
});
await userEvent.type(codeTextBox, codeValue);
expect(codeTextBox).toHaveValue(`${codeValue}\n\n`);
await act(async () => {
await userEvent.click(checkbox);
});
await userEvent.click(checkbox);
await userEvent.tab();
expect(addFilterBtn).toBeDisabled();
await act(async () => {
await userEvent.type(nameTextBox, nameValue);
});
expect(nameTextBox).toHaveValue(nameValue);
await userEvent.paste(nameValue);
expect(nameTextBox).toHaveValue(`${nameValue}`);
await userEvent.tab();
expect(addFilterBtn).toBeEnabled();
await act(async () => {
await userEvent.click(addFilterBtn);
});
await userEvent.click(addFilterBtn);
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1);
expect(addFilterMock).toHaveBeenCalledWith({
@ -247,15 +230,19 @@ describe('AddFilter component', () => {
});
it('should use sliced code as the filter name if filter name is empty', async () => {
await act(() => {
renderComponent({
addFilter: addFilterMock,
activeFilterHandler: activeFilterHandlerMock,
toggleIsOpen: toggleModelMock,
});
});
const codeTextBox = screen.getAllByRole(
'textbox'
)[0] as HTMLTextAreaElement;
const nameTextBox = screen.getAllByRole('textbox')[1];
const addFilterBtn = screen.getByRole('button', { name: /Add filter/i });
act(() => {
// await userEvent.clear(nameTextBox);
// codeTextBox.focus();
// await userEvent.clear(codeTextBox);
fireEvent.input(nameTextBox, {
inputType: '',
});

View file

@ -3,7 +3,7 @@ import EditFilter, {
EditFilterProps,
} from 'components/Topics/Topic/Messages/Filters/EditFilter';
import { render } from 'lib/testHelpers';
import { screen, fireEvent, within, act } from '@testing-library/react';
import { screen, within, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { FilterEdit } from 'components/Topics/Topic/Messages/Filters/FilterModal';
@ -32,9 +32,7 @@ describe('EditFilter component', () => {
it('closes editFilter modal', async () => {
const toggleEditModal = jest.fn();
await act(() => {
renderComponent({ toggleEditModal });
});
renderComponent({ toggleEditModal });
await userEvent.click(screen.getByRole('button', { name: /Cancel/i }));
expect(toggleEditModal).toHaveBeenCalledTimes(1);
});
@ -43,18 +41,15 @@ describe('EditFilter component', () => {
const toggleEditModal = jest.fn();
const editSavedFilter = jest.fn();
await renderComponent({ toggleEditModal, editSavedFilter });
renderComponent({ toggleEditModal, editSavedFilter });
const inputs = screen.getAllByRole('textbox');
const textAreaElement = inputs[0] as HTMLTextAreaElement;
const inputNameElement = inputs[1];
await act(async () => {
textAreaElement.focus();
await userEvent.paste('edited code');
textAreaElement.focus();
await userEvent.type(inputNameElement, 'edited name');
fireEvent.submit(screen.getByRole('form'));
});
textAreaElement.focus();
await userEvent.paste('edited code');
await userEvent.type(inputNameElement, 'edited name');
await userEvent.click(screen.getByRole('button', { name: /Save/i }));
expect(toggleEditModal).toHaveBeenCalledTimes(1);
expect(editSavedFilter).toHaveBeenCalledTimes(1);
});

View file

@ -21,18 +21,18 @@ const renderComponent = (props?: Partial<FilterModalProps>) =>
{...props}
/>
);
describe('FilterModal component', () => {
beforeEach(async () => {
it('renders component with add filter modal', async () => {
await act(() => {
renderComponent();
});
});
it('renders component with add filter modal', () => {
expect(
screen.getByRole('heading', { name: /add filter/i, level: 3 })
).toBeInTheDocument();
});
it('renders component with edit filter modal', async () => {
renderComponent();
await userEvent.click(screen.getByRole('savedFilterText'));
await userEvent.click(screen.getByText('Edit'));
expect(

View file

@ -5,7 +5,7 @@ import Filters, {
SeekTypeOptions,
} from 'components/Topics/Topic/Messages/Filters/Filters';
import { EventSourceMock, render, WithRoute } from 'lib/testHelpers';
import { act, screen, within, waitFor } from '@testing-library/react';
import { screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import TopicMessagesContext, {
ContextProps,
@ -39,7 +39,7 @@ const topicName = 'topic-name';
const renderComponent = (
props: Partial<FiltersProps> = {},
ctx: ContextProps = defaultContextValue
) => {
) =>
render(
<WithRoute path={clusterTopicPath()}>
<TopicMessagesContext.Provider value={ctx}>
@ -57,7 +57,6 @@ const renderComponent = (
</WithRoute>,
{ initialEntries: [clusterTopicPath(clusterName, topicName)] }
);
};
beforeEach(async () => {
(useTopicDetails as jest.Mock).mockImplementation(() => ({
@ -86,10 +85,8 @@ describe('Filters component', () => {
describe('Input elements', () => {
const inputValue = 'Hello World!';
beforeEach(async () => {
await act(() => {
renderComponent();
});
beforeEach(() => {
renderComponent();
});
it('search input', async () => {
@ -110,19 +107,15 @@ describe('Filters component', () => {
const seekTypeSelect = screen.getAllByRole('listbox');
const option = screen.getAllByRole('option');
await act(async () => {
await userEvent.click(seekTypeSelect[0]);
});
await userEvent.click(seekTypeSelect[0]);
await act(async () => {
await userEvent.selectOptions(seekTypeSelect[0], ['Timestamp']);
});
await userEvent.selectOptions(seekTypeSelect[0], ['Timestamp']);
expect(option[0]).toHaveTextContent('Timestamp');
const timestampInput = screen.getByPlaceholderText('Select timestamp');
expect(timestampInput).toHaveValue('');
await waitFor(() => userEvent.type(timestampInput, inputValue));
await userEvent.type(timestampInput, inputValue);
expect(timestampInput).toHaveValue(inputValue);
expect(screen.getByText('Submit')).toBeInTheDocument();
@ -173,13 +166,11 @@ describe('Filters component', () => {
it('renders addFilter modal', async () => {
renderComponent();
await act(async () => {
await userEvent.click(
screen.getByRole('button', {
name: /add filters/i,
})
);
});
await userEvent.click(
screen.getByRole('button', {
name: /add filters/i,
})
);
expect(screen.getByTestId('messageFilterModal')).toBeInTheDocument();
});
@ -187,13 +178,11 @@ describe('Filters component', () => {
beforeEach(async () => {
renderComponent();
await act(async () => {
await userEvent.click(
screen.getByRole('button', {
name: /add filters/i,
})
);
});
await userEvent.click(
screen.getByRole('button', {
name: 'Add Filters',
})
);
const filterName = 'filter name';
const filterCode = 'filter code';
@ -205,34 +194,34 @@ describe('Filters component', () => {
const textAreaElement = textBoxElements[0] as HTMLTextAreaElement;
const inputNameElement = textBoxElements[1];
await act(async () => {
textAreaElement.focus();
await userEvent.paste(filterName);
await userEvent.type(inputNameElement, filterCode);
});
expect(textAreaElement.value).toEqual(`${filterName}\n\n`);
expect(inputNameElement).toHaveValue(filterCode);
textAreaElement.focus();
await userEvent.paste(filterCode);
await userEvent.type(inputNameElement, filterName);
await act(async () => {
await userEvent.click(
within(messageFilterModal).getByRole('button', {
name: /add filter/i,
})
);
});
expect(textAreaElement).toHaveValue(`${filterCode}\n\n`);
expect(inputNameElement).toHaveValue('filter name');
expect(
screen.getByRole('button', {
name: 'Add filter',
})
).toBeEnabled();
await userEvent.click(
screen.getByRole('button', {
name: 'Add filter',
})
);
await userEvent.tab();
});
it('shows saved smart filter', () => {
it('shows saved smart filter', async () => {
expect(screen.getByTestId('activeSmartFilter')).toBeInTheDocument();
});
it('delete the active smart Filter', async () => {
const smartFilterElement = screen.getByTestId('activeSmartFilter');
const deleteIcon = within(smartFilterElement).getByText('mock-CloseIcon');
await act(async () => {
await userEvent.click(deleteIcon);
});
await userEvent.click(deleteIcon);
const anotherSmartFilterElement =
screen.queryByTestId('activeSmartFilter');

View file

@ -15,8 +15,8 @@ describe('SavedFilter Component', () => {
{ name: 'One More Filter', code: 'code1' },
];
const setUpComponent = (props: Partial<Props> = {}) => {
return render(
const setUpComponent = (props: Partial<Props> = {}) =>
render(
<SavedFilters
filters={props.filters || mockFilters}
onEdit={props.onEdit || jest.fn()}
@ -26,7 +26,6 @@ describe('SavedFilter Component', () => {
deleteFilter={props.deleteFilter || jest.fn()}
/>
);
};
const getSavedFilters = () => screen.getAllByRole('savedFilter');

View file

@ -40,8 +40,8 @@ describe('Message component', () => {
props: Partial<Props> = {
message: mockMessage,
}
) => {
return render(
) =>
render(
<table>
<tbody>
<Message
@ -52,7 +52,6 @@ describe('Message component', () => {
</tbody>
</table>
);
};
it('shows the data in the table row', () => {
renderComponent();

View file

@ -27,14 +27,13 @@ jest.mock('components/Topics/New/New', () => () => (
describe('Topics Component', () => {
const clusterName = 'clusterName';
const topicName = 'topicName';
const setUpComponent = (path: string) => {
return render(
const setUpComponent = (path: string) =>
render(
<WithRoute path={getNonExactPath(clusterTopicsPath())}>
<Topics />
</WithRoute>,
{ initialEntries: [path] }
);
};
it('should check if the page is Topics List rendered', () => {
setUpComponent(clusterTopicsPath(clusterName));

View file

@ -6,9 +6,9 @@ const SelectRowHeader: React.FC<HeaderContext<unknown, unknown>> = ({
table,
}) => (
<IndeterminateCheckbox
checked={table.getIsAllPageRowsSelected()}
indeterminate={table.getIsSomePageRowsSelected()}
onChange={table.getToggleAllPageRowsSelectedHandler()}
checked={table.getIsAllRowsSelected()}
indeterminate={table.getIsSomeRowsSelected()}
onChange={table.getToggleAllRowsSelectedHandler()}
/>
);