fix ui tests, add alarm assignee tests to suite

This commit is contained in:
Seraphym-Tuhai 2023-05-31 23:29:00 +03:00
parent ceda0f14e6
commit 7116491824
16 changed files with 99 additions and 46 deletions

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.msa.ui.base;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@ -42,7 +43,6 @@ abstract public class AbstractBasePage {
protected Actions actions; protected Actions actions;
protected JavascriptExecutor js; protected JavascriptExecutor js;
public AbstractBasePage(WebDriver driver) { public AbstractBasePage(WebDriver driver) {
this.driver = driver; this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofMillis(WAIT_TIMEOUT)); this.wait = new WebDriverWait(driver, Duration.ofMillis(WAIT_TIMEOUT));
@ -154,7 +154,11 @@ abstract public class AbstractBasePage {
} }
public void waitUntilAttributeContains(WebElement element, String attribute, String value) { public void waitUntilAttributeContains(WebElement element, String attribute, String value) {
wait.until(ExpectedConditions.attributeContains(element, attribute, value)); try {
wait.until(ExpectedConditions.attributeContains(element, attribute, value));
} catch (WebDriverException e) {
fail("Failed to wait until attribute '" + attribute + "' of element '" + element + "' contains value '" + value + "'");
}
} }
public void goToNextTab(int tabNumber) { public void goToNextTab(int tabNumber) {
@ -189,4 +193,25 @@ abstract public class AbstractBasePage {
public void pull(WebElement element, int xOffset, int yOffset) { public void pull(WebElement element, int xOffset, int yOffset) {
actions.clickAndHold(element).moveByOffset(xOffset, yOffset).release().perform(); actions.clickAndHold(element).moveByOffset(xOffset, yOffset).release().perform();
} }
public void waitUntilAttributeToBe(String locator, String attribute, String value) {
try {
wait.until(ExpectedConditions.attributeToBe(By.xpath(locator), attribute, value));
} catch (WebDriverException e) {
fail("Failed to wait until attribute '" + attribute + "' of element located by '" + locator + "' is '" + value + "'");
}
}
public void clearInputField(WebElement element) {
element.click();
element.sendKeys(Keys.CONTROL + "A" + Keys.BACK_SPACE);
}
public void waitUntilAttributeToBeNotEmpty(WebElement element, String attribute) {
try {
wait.until(ExpectedConditions.attributeToBeNotEmpty(element, attribute));
} catch (WebDriverException e) {
fail("Failed to wait until attribute '" + attribute + "' of element '" + element + "' is not empty");
}
}
} }

View File

@ -55,7 +55,6 @@ import java.io.ByteArrayInputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -231,13 +230,9 @@ abstract public class AbstractDriverBaseTest extends AbstractContainerTest {
} }
} }
public WebStorage getWebStorage() {
return webStorage = (WebStorage) driver;
}
public void clearStorage() { public void clearStorage() {
getWebStorage().getLocalStorage().clear(); getJs().executeScript("window.localStorage.clear();");
getWebStorage().getSessionStorage().clear(); getJs().executeScript("window.sessionStorage.clear();");
} }
public void deleteAlarmById(AlarmId alarmId) { public void deleteAlarmById(AlarmId alarmId) {

View File

@ -35,6 +35,7 @@ public class AlarmDetailsEntityTabElements extends OtherPageElements {
private static final String ALARM_DETAILS_BTN = "//span[text() = '%s']/ancestor::mat-row//mat-icon[contains(text(),'more_horiz')]/parent::button"; private static final String ALARM_DETAILS_BTN = "//span[text() = '%s']/ancestor::mat-row//mat-icon[contains(text(),'more_horiz')]/parent::button";
private static final String ACCESS_FORBIDDEN_DIALOG_VIEW = "//h2[text() = 'Access Forbidden']/parent::tb-confirm-dialog"; private static final String ACCESS_FORBIDDEN_DIALOG_VIEW = "//h2[text() = 'Access Forbidden']/parent::tb-confirm-dialog";
private static final String ALARM_ASSIGNEE_DROPDOWN = "//tb-alarm-assignee-panel"; private static final String ALARM_ASSIGNEE_DROPDOWN = "//tb-alarm-assignee-panel";
private static final String NO_USERS_FOUND_MESSAGE = "//div[@class='tb-not-found-content']/span";
public WebElement assignBtn(String type) { public WebElement assignBtn(String type) {
return waitUntilElementToBeClickable(String.format(ASSIGN_BTN, type)); return waitUntilElementToBeClickable(String.format(ASSIGN_BTN, type));
@ -75,4 +76,8 @@ public class AlarmDetailsEntityTabElements extends OtherPageElements {
public WebElement alarmAssigneeDropdown() { public WebElement alarmAssigneeDropdown() {
return waitUntilVisibilityOfElementLocated(ALARM_ASSIGNEE_DROPDOWN); return waitUntilVisibilityOfElementLocated(ALARM_ASSIGNEE_DROPDOWN);
} }
public WebElement noUsersFoundMessage() {
return waitUntilVisibilityOfElementLocated(NO_USERS_FOUND_MESSAGE);
}
} }

View File

@ -146,6 +146,14 @@ public class CustomerPageHelper extends CustomerPageElements {
submitAssignedBtn().click(); submitAssignedBtn().click();
} }
public void assignedDashboard(String dashboardName) {
plusBtn().click();
assignedField().click();
entityFromList(dashboardName).click();
assignedField().sendKeys(Keys.ESCAPE);
submitAssignedBtn().click();
}
public boolean customerIsNotPresent(String title) { public boolean customerIsNotPresent(String title) {
return elementsIsNotPresent(getEntity(title)); return elementsIsNotPresent(getEntity(title));
} }
@ -169,4 +177,13 @@ public class CustomerPageHelper extends CustomerPageElements {
} }
customerDetailsAlarmsBtn().click(); customerDetailsAlarmsBtn().click();
} }
public void disableHideHomeDashboardToolbar() {
hideHomeDashboardToolbarCheckbox().click();
waitUntilAttributeToBe("//mat-checkbox[@formcontrolname='homeDashboardHideToolbar']//input", "class", "mdc-checkbox__native-control");
}
public void waitUntilDashboardFieldToBeNotEmpty() {
waitUntilAttributeToBeNotEmpty(editMenuDashboardField(), "value");
}
} }

View File

@ -30,13 +30,12 @@ public class DashboardPageElements extends OtherPageElementsHelper {
private static final String MANAGE_ASSIGNED_ENTITY_LIST_FIELD = "//input[@formcontrolname='entity']"; private static final String MANAGE_ASSIGNED_ENTITY_LIST_FIELD = "//input[@formcontrolname='entity']";
private static final String MANAGE_ASSIGNED_ENTITY = "//mat-option//span[contains(text(),'%s')]"; private static final String MANAGE_ASSIGNED_ENTITY = "//mat-option//span[contains(text(),'%s')]";
private static final String MANAGE_ASSIGNED_UPDATE_BTN = "//button[@type='submit']"; private static final String MANAGE_ASSIGNED_UPDATE_BTN = "//button[@type='submit']";
private static final String EDIT_BTN = "//mat-icon[text() = 'edit']/parent::button"; private static final String EDIT_BTN = "//mat-icon[text() = 'edit']/parent::button[@mat-stroked-button]";
private static final String ADD_BTN = "//tb-footer-fab-buttons//button"; private static final String ADD_BTN = "//mat-fab-actions//mat-icon[text() = 'add']/parent::button";
private static final String CREAT_NEW_DASHBOARD_BTN = "//mat-icon[text() = 'insert_drive_file']/parent::button";
private static final String ALARM_WIDGET_BUNDLE = "//mat-card-title[text() = 'Alarm widgets']/ancestor::mat-card"; private static final String ALARM_WIDGET_BUNDLE = "//mat-card-title[text() = 'Alarm widgets']/ancestor::mat-card";
private static final String ALARM_TABLE_WIDGET = "//img[@alt='Alarms table']/ancestor::mat-card"; private static final String ALARM_TABLE_WIDGET = "//img[@alt='Alarms table']/ancestor::mat-card";
private static final String WIDGET_SE_CORNER = "//div[contains(@class,'handle-se')]"; private static final String WIDGET_SE_CORNER = "//div[contains(@class,'handle-se')]";
private static final String DONE_BTN = "//tb-footer-fab-buttons/following-sibling::button//mat-icon[text() = 'done']/parent::button"; private static final String SAVE_BTN = "//mat-icon[text() = 'done']/parent::button[@fxhide.lt-lg]";
public List<WebElement> entityTitles() { public List<WebElement> entityTitles() {
return waitUntilVisibilityOfElementsLocated(TITLES); return waitUntilVisibilityOfElementsLocated(TITLES);
@ -66,10 +65,6 @@ public class DashboardPageElements extends OtherPageElementsHelper {
return waitUntilElementToBeClickable(ADD_BTN); return waitUntilElementToBeClickable(ADD_BTN);
} }
public WebElement createNewDashboardBtn() {
return waitUntilElementToBeClickable(CREAT_NEW_DASHBOARD_BTN);
}
public WebElement alarmWidgetBundle() { public WebElement alarmWidgetBundle() {
return waitUntilElementToBeClickable(ALARM_WIDGET_BUNDLE); return waitUntilElementToBeClickable(ALARM_WIDGET_BUNDLE);
} }
@ -82,7 +77,7 @@ public class DashboardPageElements extends OtherPageElementsHelper {
return waitUntilElementToBeClickable(WIDGET_SE_CORNER); return waitUntilElementToBeClickable(WIDGET_SE_CORNER);
} }
public WebElement doneBtn() { public WebElement saveBtn() {
return waitUntilVisibilityOfElementLocated(DONE_BTN); return waitUntilVisibilityOfElementLocated(SAVE_BTN);
} }
} }

View File

@ -40,7 +40,6 @@ public class DashboardPageHelper extends DashboardPageElements {
public void openSelectWidgetsBundleMenu() { public void openSelectWidgetsBundleMenu() {
addBtn().click(); addBtn().click();
createNewDashboardBtn().click();
} }
public void openCreateWidgetPopup() { public void openCreateWidgetPopup() {

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.msa.ui.tests.assignee; package org.thingsboard.server.msa.ui.tests.alarmassignee;
import io.qameta.allure.Epic; import io.qameta.allure.Epic;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.msa.ui.tests.assignee; package org.thingsboard.server.msa.ui.tests.alarmassignee;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
@ -161,15 +161,13 @@ public class AssignDetailsTabAssignTest extends AbstractAssignTest {
} }
@Description("Search by name") @Description("Search by name")
@Test(groups = "broken") @Test
public void searchByName() { public void searchByName() {
sideBarMenuView.goToDevicesPage(); sideBarMenuView.goToDevicesPage();
devicePage.openDeviceAlarms(deviceName); devicePage.openDeviceAlarms(deviceName);
alarmPage.searchAlarm(alarmType, userName); alarmPage.searchAlarm(alarmType, userName);
alarmPage.setUsers();
assertThat(alarmPage.getUsers()).hasSize(1).as("Search result contains search input").contains(userName); assertIsDisplayed(alarmPage.noUsersFoundMessage());
alarmPage.assignUsers().forEach(this::assertIsDisplayed);
} }
@Description("Assign alarm to yourself from details of alarm") @Description("Assign alarm to yourself from details of alarm")

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.msa.ui.tests.assignee; package org.thingsboard.server.msa.ui.tests.alarmassignee;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.msa.ui.tests.assignee; package org.thingsboard.server.msa.ui.tests.alarmassignee;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
@ -56,7 +56,7 @@ public class AssignFromAlarmWidgetTest extends AbstractAssignTest {
createWidgetPopup.addAliasBtn().click(); createWidgetPopup.addAliasBtn().click();
createWidgetPopup.addWidgetBtn().click(); createWidgetPopup.addWidgetBtn().click();
dashboardPage.increaseSizeOfTheWidget(); dashboardPage.increaseSizeOfTheWidget();
dashboardPage.doneBtn().click(); dashboardPage.saveBtn().click();
} }
@AfterClass @AfterClass
@ -135,12 +135,10 @@ public class AssignFromAlarmWidgetTest extends AbstractAssignTest {
} }
@Description("Search by name") @Description("Search by name")
@Test(groups = "broken") @Test
public void searchByName() { public void searchByName() {
alarmWidget.searchAlarm(alarmType, userName); alarmWidget.searchAlarm(alarmType, userName);
alarmWidget.setUsers();
assertThat(alarmWidget.getUsers()).hasSize(1).as("Search result contains search input").contains(userName); assertIsDisplayed(alarmWidget.noUsersFoundMessage());
alarmWidget.assignUsers().forEach(this::assertIsDisplayed);
} }
} }

View File

@ -207,9 +207,9 @@ public class CreateCustomerTest extends AbstractDriverBaseTest {
sideBarMenuView.customerBtn().click(); sideBarMenuView.customerBtn().click();
customerPage.plusBtn().click(); customerPage.plusBtn().click();
customerPage.titleFieldAddEntityView().sendKeys(customerName); customerPage.addCustomerViewEnterName(customerName);
customerPage.phoneNumberAddEntityView().sendKeys(number); customerPage.enterText(customerPage.phoneNumberAddEntityView(), number);
customerPage.phoneNumberAddEntityView().sendKeys(Keys.CONTROL + "A" + Keys.BACK_SPACE); customerPage.clearInputField(customerPage.phoneNumberAddEntityView());
customerPage.addBtnC().click(); customerPage.addBtnC().click();
this.customerName = customerName; this.customerName = customerName;
customerPage.entity(customerName).click(); customerPage.entity(customerName).click();

View File

@ -204,31 +204,32 @@ public class CustomerEditMenuTest extends AbstractDriverBaseTest {
@Epic("Customers smoke tests") @Epic("Customers smoke tests")
@Feature("Edit customer") @Feature("Edit customer")
@Test(priority = 20, groups = "smoke") @Test(priority = 20, groups = { "smoke", "broken" })
@Description("Assigned dashboard without hide") @Description("Assigned dashboard without hide")
public void assignedDashboardWithoutHide() { public void assignedDashboardWithoutHide() {
String customerName = ENTITY_NAME + random(); String customerName = ENTITY_NAME + random();
String dashboardName = "Firmware";
testRestClient.postCustomer(defaultCustomerPrototype(customerName)); testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName; this.customerName = customerName;
sideBarMenuView.customerBtn().click(); sideBarMenuView.customerBtn().click();
customerPage.manageCustomersDashboardsBtn(customerName).click(); customerPage.manageCustomersDashboardsBtn(customerName).click();
customerPage.assignedDashboard(); customerPage.assignedDashboard(dashboardName);
sideBarMenuView.customerBtn().click(); sideBarMenuView.customerBtn().click();
customerPage.entity(customerName).click(); customerPage.entity(customerName).click();
jsClick(customerPage.editPencilBtn()); jsClick(customerPage.editPencilBtn());
customerPage.chooseDashboard(customerPage.getDashboard()); customerPage.chooseDashboard(dashboardName);
customerPage.hideHomeDashboardToolbarCheckbox().click(); customerPage.disableHideHomeDashboardToolbar();
customerPage.doneBtnEditView().click(); customerPage.doneBtnEditView().click();
customerPage.waitUntilDashboardFieldToBeNotEmpty();
customerPage.setDashboardFromView(); customerPage.setDashboardFromView();
customerPage.closeEntityViewBtn().click(); customerPage.closeEntityViewBtn().click();
jsClick(customerPage.manageCustomersUserBtn(customerName)); jsClick(customerPage.manageCustomersUserBtn(customerName));
customerPage.createCustomersUser(); customerPage.createCustomersUser();
jsClick(customerPage.userLoginBtn()); jsClick(customerPage.userLoginBtn());
Assert.assertNotNull(customerPage.usersWidget());
Assert.assertTrue(customerPage.usersWidget().isDisplayed()); Assert.assertTrue(customerPage.usersWidget().isDisplayed());
Assert.assertEquals(customerPage.getDashboard(), customerPage.getDashboardFromView()); Assert.assertEquals(dashboardName, customerPage.getDashboardFromView());
Assert.assertNotNull(customerPage.stateController()); Assert.assertNotNull(customerPage.stateController());
Assert.assertNotNull(customerPage.filterBtn()); Assert.assertNotNull(customerPage.filterBtn());
Assert.assertNotNull(customerPage.timeBtn()); Assert.assertNotNull(customerPage.timeBtn());

View File

@ -16,7 +16,7 @@
package org.thingsboard.server.msa.ui.tests.devicessmoke; package org.thingsboard.server.msa.ui.tests.devicessmoke;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Epic; import io.qameta.allure.Feature;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.msa.ui.base.AbstractBasePage.random; import static org.thingsboard.server.msa.ui.base.AbstractBasePage.random;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME; import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
@Epic("Filter devices (By device profile and state)") @Feature("Filter devices (By device profile and state)")
public class DeviceFilterTest extends AbstractDeviceTest { public class DeviceFilterTest extends AbstractDeviceTest {
private String activeDeviceName; private String activeDeviceName;

View File

@ -18,7 +18,7 @@
--> -->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Assignee ui tests"> <suite name="Assignee alarm ui tests">
<listeners> <listeners>
<listener class-name="org.thingsboard.server.msa.ui.listeners.RetryTestListener"/> <listener class-name="org.thingsboard.server.msa.ui.listeners.RetryTestListener"/>
</listeners> </listeners>
@ -29,7 +29,7 @@
</run> </run>
</groups> </groups>
<packages> <packages>
<package name="org.thingsboard.server.msa.ui.tests.assignee.*"/> <package name="org.thingsboard.server.msa.ui.tests.alarmassignee.*"/>
</packages> </packages>
</test> </test>
</suite> </suite>

View File

@ -77,4 +77,14 @@
<package name="org.thingsboard.server.msa.ui.tests.devicessmoke"/> <package name="org.thingsboard.server.msa.ui.tests.devicessmoke"/>
</packages> </packages>
</test> </test>
<test name="Alarm assignee tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.alarmassignee.*"/>
</packages>
</test>
</suite> </suite>

View File

@ -72,4 +72,14 @@
<package name="org.thingsboard.server.msa.ui.tests.devicessmoke"/> <package name="org.thingsboard.server.msa.ui.tests.devicessmoke"/>
</packages> </packages>
</test> </test>
<test name="Alarm assignee tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.alarmassignee.*"/>
</packages>
</test>
</suite> </suite>