Browse Source

Merge branch 'master' into develop/3.5

pull/7952/head
Andrii Shvaika 3 years ago
parent
commit
0a0099207e
  1. 2
      application/src/main/data/upgrade/3.4.1/schema_update.sql
  2. 11
      application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
  3. 19
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  4. 2
      application/src/main/java/org/thingsboard/server/service/session/DefaultDeviceSessionCacheService.java
  5. 11
      msa/black-box-tests/README.md
  6. 28
      msa/black-box-tests/pom.xml
  7. 2
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
  8. 7
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java
  9. 28
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/DisableUIListeners.java
  10. 85
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/SeleniumRemoteWebDriverTest.java
  11. 45
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestListener.java
  12. 7
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java
  13. 80
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java
  14. 3
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java
  15. 2
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java
  16. 4
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java
  17. 2
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java
  18. 143
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/base/AbstractBasePage.java
  19. 123
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/base/AbstractDriverBaseTest.java
  20. 42
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/listeners/RetryAnalyzer.java
  21. 33
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/listeners/RetryTestListener.java
  22. 282
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CustomerPageElements.java
  23. 145
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CustomerPageHelper.java
  24. 53
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DashboardPageElements.java
  25. 40
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DashboardPageHelper.java
  26. 43
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/LoginPageElements.java
  27. 31
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/LoginPageHelper.java
  28. 48
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OpenRuleChainPageElements.java
  29. 38
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OpenRuleChainPageHelper.java
  30. 249
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OtherPageElements.java
  31. 113
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OtherPageElementsHelper.java
  32. 128
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/RuleChainsPageElements.java
  33. 124
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/RuleChainsPageHelper.java
  34. 42
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/SideBarMenuViewElements.java
  35. 185
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/CreateCustomerTest.java
  36. 293
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/CustomerEditMenuTest.java
  37. 102
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/DeleteCustomerTest.java
  38. 92
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/DeleteSeveralCustomerTest.java
  39. 67
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersAssetsTest.java
  40. 66
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersDashboardsTest.java
  41. 66
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersDevicesTest.java
  42. 67
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersEdgesTest.java
  43. 67
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersUsersTest.java
  44. 69
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/SearchCustomerTest.java
  45. 131
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/SortByNameTest.java
  46. 142
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/CreateRuleChainImportTest.java
  47. 171
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/CreateRuleChainTest.java
  48. 171
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/DeleteRuleChainTest.java
  49. 111
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/DeleteSeveralRuleChainsTest.java
  50. 89
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/MakeRuleChainRootTest.java
  51. 93
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/OpenRuleChainTest.java
  52. 160
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/RuleChainEditMenuTest.java
  53. 70
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/SearchRuleChainTest.java
  54. 132
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/SortByNameTest.java
  55. 88
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/SortByTimeTest.java
  56. 37
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/Const.java
  57. 77
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/DataProviderCredential.java
  58. 34
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/EntityPrototypes.java
  59. 50
      msa/black-box-tests/src/test/resources/all.xml
  60. 2
      msa/black-box-tests/src/test/resources/allure.properties
  61. 2
      msa/black-box-tests/src/test/resources/connectivity.xml
  62. 37
      msa/black-box-tests/src/test/resources/docker-selenium.yml
  63. 20
      msa/black-box-tests/src/test/resources/forImport.json
  64. 16
      msa/black-box-tests/src/test/resources/forImport.txt
  65. 35
      msa/black-box-tests/src/test/resources/smokesCustomer.xml
  66. 35
      msa/black-box-tests/src/test/resources/smokesRuleChain.xml
  67. 45
      msa/black-box-tests/src/test/resources/uiTests.xml
  68. 30
      pom.xml
  69. 1
      ui-ngx/src/app/core/api/widget-subscription.ts

2
application/src/main/data/upgrade/3.4.1/schema_update.sql

@ -88,7 +88,7 @@ $$
-- in case of running the upgrade script a second time:
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_edge_event')) THEN
ALTER TABLE edge_event RENAME TO old_edge_event;
CREATE INDEX IF NOT EXISTS idx_old_blob_entity_created_time_tmp ON old_blob_entity(created_time);
CREATE INDEX IF NOT EXISTS idx_old_edge_event_created_time_tmp ON old_edge_event(created_time);
ALTER INDEX IF EXISTS idx_edge_event_tenant_id_and_created_time RENAME TO idx_old_edge_event_tenant_id_and_created_time;
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts

11
application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java

@ -1433,7 +1433,8 @@ public class ControllerConstants {
protected static final String ATTRIBUTES_SCOPE_DESCRIPTION = "A string value representing the attributes scope. For example, 'SERVER_SCOPE'.";
protected static final String ATTRIBUTES_KEYS_DESCRIPTION = "A string value representing the comma-separated list of attributes keys. For example, 'active,inactivityAlarmTime'.";
protected static final String ATTRIBUTES_SCOPE_ALLOWED_VALUES = "SERVER_SCOPE, CLIENT_SCOPE, SHARED_SCOPE";
protected static final String ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES = "SERVER_SCOPE, SHARED_SCOPE";
protected static final String ATTRIBUTES_SCOPE_ALLOWED_VALUES = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES + ", CLIENT_SCOPE";
protected static final String ATTRIBUTES_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}'. See API call description for more details.";
protected static final String TELEMETRY_KEYS_BASE_DESCRIPTION = "A string value representing the comma-separated list of telemetry keys.";
@ -1459,10 +1460,12 @@ public class ControllerConstants {
protected static final String SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR = "The exception was thrown during processing the request. " +
"Platform creates an audit log event about entity timeseries updates with action type 'TIMESERIES_UPDATED' that includes an error stacktrace.";
protected static final String ENTITY_ATTRIBUTE_SCOPES = " List of possible attribute scopes depends on the entity type: " +
protected static final String ENTITY_ATTRIBUTE_SCOPES_TEMPLATE = " List of possible attribute scopes depends on the entity type: " +
"\n\n * SERVER_SCOPE - supported for all entity types;" +
"\n * CLIENT_SCOPE - supported for devices;" +
"\n * SHARED_SCOPE - supported for devices. "+ "\n\n";
"\n * SHARED_SCOPE - supported for devices";
protected static final String ENTITY_SAVE_ATTRIBUTE_SCOPES = ENTITY_ATTRIBUTE_SCOPES_TEMPLATE + ".\n\n";
protected static final String ENTITY_GET_ATTRIBUTE_SCOPES = ENTITY_ATTRIBUTE_SCOPES_TEMPLATE +
";\n * CLIENT_SCOPE - supported for devices. " + "\n\n";
protected static final String ATTRIBUTE_DATA_EXAMPLE = "[\n" +
" {\"key\": \"stringAttributeKey\", \"value\": \"value\", \"lastUpdateTs\": 1609459200000},\n" +

19
application/src/main/java/org/thingsboard/server/controller/TelemetryController.java

@ -58,7 +58,6 @@ import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.kv.Aggregation;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseDeleteTsKvQuery;
@ -92,11 +91,9 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ -104,13 +101,15 @@ import java.util.stream.Collectors;
import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_JSON_REQUEST_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_KEYS_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SCOPE_ALLOWED_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SCOPE_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTE_DATA_EXAMPLE;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ATTRIBUTE_SCOPES;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_GET_ATTRIBUTE_SCOPES;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_SAVE_ATTRIBUTE_SCOPES;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.INVALID_STRUCTURE_OF_THE_REQUEST;
@ -241,7 +240,7 @@ public class TelemetryController extends BaseController {
@ApiOperation(value = "Get attributes by scope (getAttributesByScope)",
notes = "Returns all attributes of a specified scope that belong to specified entity." +
ENTITY_ATTRIBUTE_SCOPES +
ENTITY_GET_ATTRIBUTE_SCOPES +
"Use optional 'keys' parameter to return specific attributes."
+ "\n Example of the result: \n\n"
+ MARKDOWN_CODE_BLOCK_START
@ -383,7 +382,7 @@ public class TelemetryController extends BaseController {
@ResponseBody
public DeferredResult<ResponseEntity> saveDeviceAttributes(
@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("deviceId") String deviceIdStr,
@ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope,
@ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope,
@ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException {
try {
EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr);
@ -395,7 +394,7 @@ public class TelemetryController extends BaseController {
@ApiOperation(value = "Save entity attributes (saveEntityAttributesV1)",
notes = "Creates or updates the entity attributes based on Entity Id and the specified attribute scope. " +
ENTITY_ATTRIBUTE_SCOPES +
ENTITY_SAVE_ATTRIBUTE_SCOPES +
SAVE_ATTRIBUTES_REQUEST_PAYLOAD
+ INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
produces = MediaType.APPLICATION_JSON_VALUE)
@ -411,7 +410,7 @@ public class TelemetryController extends BaseController {
public DeferredResult<ResponseEntity> saveEntityAttributesV1(
@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType,
@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr,
@ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope,
@ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope,
@ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException {
try {
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
@ -423,7 +422,7 @@ public class TelemetryController extends BaseController {
@ApiOperation(value = "Save entity attributes (saveEntityAttributesV2)",
notes = "Creates or updates the entity attributes based on Entity Id and the specified attribute scope. " +
ENTITY_ATTRIBUTE_SCOPES +
ENTITY_SAVE_ATTRIBUTE_SCOPES +
SAVE_ATTRIBUTES_REQUEST_PAYLOAD
+ INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
produces = MediaType.APPLICATION_JSON_VALUE)
@ -439,7 +438,7 @@ public class TelemetryController extends BaseController {
public DeferredResult<ResponseEntity> saveEntityAttributesV2(
@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType,
@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr,
@ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope,
@ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope,
@ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException {
try {
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);

2
application/src/main/java/org/thingsboard/server/service/session/DefaultDeviceSessionCacheService.java

@ -52,7 +52,7 @@ public class DefaultDeviceSessionCacheService implements DeviceSessionCacheServi
@Override
public DeviceSessionsCacheEntry put(DeviceId deviceId, DeviceSessionsCacheEntry sessions) {
log.debug("[{}] Pushing session data to cache: {}", deviceId, sessions);
cache.putIfAbsent(deviceId, sessions);
cache.put(deviceId, sessions);
return sessions;
}
}

11
msa/black-box-tests/README.md

@ -30,9 +30,18 @@ As result, in REPOSITORY column, next images should be present:
mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.hybridMode=true
To run the black box tests with using local env run tests in the [msa/black-box-tests](../black-box-tests) directory with runLocal property:
- To run the black box tests with using local env run tests in the [msa/black-box-tests](../black-box-tests) directory with runLocal property:
mvn clean install -DblackBoxTests.skip=false -DrunLocal=true
- To run ui smoke tests in the [msa/black-box-tests](../black-box-tests) directory specifying suite name:
mvn clean install -DblackBoxTests.skip=false -Dsuite=uiTests
- To run all tests in the [msa/black-box-tests](../black-box-tests) directory specifying suite name:
mvn clean install -DblackBoxTests.skip=false -Dsuite=all

28
msa/black-box-tests/pom.xml

@ -34,6 +34,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<main.dir>${basedir}/../..</main.dir>
<suite>connectivity</suite>
</properties>
<dependencies>
@ -170,6 +171,21 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
@ -178,7 +194,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testNG.xml</suiteXmlFile>
<suiteXmlFile>src/test/resources/${suite}.xml</suiteXmlFile>
</suiteXmlFiles>
<skipTests>${blackBoxTests.skip}</skipTests>
</configuration>
@ -190,6 +206,16 @@
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>${allure-maven.version}</version>
<configuration>
<reportVersion>${allure-testng.version}</reportVersion>
<allureDownloadUrl>https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/
${allure-testng.version}/allure-commandline-${allure-testng.version}.zip</allureDownloadUrl>
</configuration>
</plugin>
</plugins>
</build>

2
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java

@ -63,7 +63,7 @@ public abstract class AbstractContainerTest {
}
}
@AfterSuite
@AfterSuite()
public void afterSuite() {
if (containerTestSuite.isActive()) {
containerTestSuite.stop();

7
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java

@ -109,7 +109,8 @@ public class ContainerTestSuite {
new File(targetDir + "docker-compose.postgres.volumes.yml"),
new File(targetDir + "docker-compose." + QUEUE_TYPE + ".yml"),
new File(targetDir + (IS_REDIS_CLUSTER ? "docker-compose.redis-cluster.yml" : "docker-compose.redis.yml")),
new File(targetDir + (IS_REDIS_CLUSTER ? "docker-compose.redis-cluster.volumes.yml" : "docker-compose.redis.volumes.yml"))
new File(targetDir + (IS_REDIS_CLUSTER ? "docker-compose.redis-cluster.volumes.yml" : "docker-compose.redis.volumes.yml")),
new File(targetDir + ("docker-selenium.yml"))
));
Map<String, String> queueEnv = new HashMap<>();
@ -230,4 +231,8 @@ public class ContainerTestSuite {
fail("failed to update file");
}
}
public DockerComposeContainer<?> getTestContainer() {
return testContainer;
}
}

28
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/DisableUIListeners.java

@ -0,0 +1,28 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface DisableUIListeners {
}

85
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/SeleniumRemoteWebDriverTest.java

@ -0,0 +1,85 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa;
import com.google.common.io.Files;
import io.qameta.allure.Attachment;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
@Slf4j
public class SeleniumRemoteWebDriverTest {
static final int WIDTH = 1680;
static final int HEIGHT = 1050;
final Dimension dimension = new Dimension(WIDTH, HEIGHT);
WebDriver driver;
@SneakyThrows
@Attachment(value = "Page screenshot", type = "image/png")
public static byte[] captureScreen(WebDriver driver, String dirPath) {
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("./target/allure-results/screenshots/" + dirPath + "//" + screenshot.getName()));
return Files.toByteArray(screenshot);
}
/**
* Requirement:
* docker run --name=chrome --rm --network=host -p 4444:4444 -p 7900:7900 --shm-size="2g" -e SE_NODE_MAX_SESSIONS=8 -e SE_NODE_OVERRIDE_MAX_SESSIONS=true -e SE_NODE_SESSION_TIMEOUT=90 -e SE_SCREEN_WIDTH=1920 -e SE_SCREEN_HEIGHT=1080 -e SE_SCREEN_DEPTH=24 -e SE_SCREEN_DPI=74 selenium/standalone-chrome
* */
@BeforeEach
void setUp() throws MalformedURLException {
log.info("Requirement:");
log.info("docker run --name=chrome --rm --network=host -p 4444:4444 -p 7900:7900 --shm-size=\"2g\" -e SE_NODE_MAX_SESSIONS=8 -e SE_NODE_OVERRIDE_MAX_SESSIONS=true -e SE_NODE_SESSION_TIMEOUT=90 -e SE_SCREEN_WIDTH=1920 -e SE_SCREEN_HEIGHT=1080 -e SE_SCREEN_DEPTH=24 -e SE_SCREEN_DPI=74 selenium/standalone-chrome");
log.info("*----------------------* Setup driver *----------------------*");
ChromeOptions options = new ChromeOptions();
RemoteWebDriver remoteWebDriver = new RemoteWebDriver(new URL("http://127.0.0.1:4444"), options);
remoteWebDriver.setFileDetector(new LocalFileDetector());
driver = remoteWebDriver;
driver.manage().window().setSize(dimension);
}
@AfterEach
void tearDown() {
log.info("*----------------------* Teardown *----------------------*");
driver.quit();
}
@Test
void testSeleniumConnection() {
driver.get("https://thingsboard.io/");
captureScreen(driver, "success");
log.info("Check the screenshot on target/allure-results/screenshots/success/screenshot???????????????.png");
//Thread.sleep(TimeUnit.SECONDS.toMillis(30));
}
}

45
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestListener.java

@ -16,18 +16,22 @@
package org.thingsboard.server.msa;
import lombok.extern.slf4j.Slf4j;
import org.testng.ITestContext;
import org.openqa.selenium.WebDriver;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import org.testng.internal.ConstructorOrMethod;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import static org.testng.internal.Utils.log;
import static org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest.captureScreen;
@Slf4j
public class TestListener extends TestListenerAdapter {
public class TestListener implements ITestListener {
WebDriver driver;
@Override
public void onTestStart(ITestResult result) {
super.onTestStart(result);
log.info("===>>> Test started: " + result.getName());
}
@ -36,10 +40,14 @@ public class TestListener extends TestListenerAdapter {
*/
@Override
public void onTestSuccess(ITestResult result) {
super.onTestSuccess(result);
if (result != null) {
log.info("<<<=== Test completed successfully: " + result.getName());
log.info("<<<=== Test completed successfully: " + result.getName());
ConstructorOrMethod consOrMethod = result.getMethod().getConstructorOrMethod();
DisableUIListeners disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableUIListeners.class);
if (disable != null) {
return;
}
driver = ((AbstractDriverBaseTest) result.getInstance()).getDriver();
captureScreen(driver, "success");
}
/**
@ -47,7 +55,28 @@ public class TestListener extends TestListenerAdapter {
*/
@Override
public void onTestFailure(ITestResult result) {
super.onTestFailure(result);
log.info("<<<=== Test failed: " + result.getName());
ConstructorOrMethod consOrMethod = result.getMethod().getConstructorOrMethod();
DisableUIListeners disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableUIListeners.class);
if (disable != null) {
return;
}
driver = ((AbstractDriverBaseTest) result.getInstance()).getDriver();
captureScreen(driver, "failure");
}
/**
* Invoked when a test skipped
*/
@Override
public void onTestSkipped(ITestResult result) {
log.info("<<<=== Test skipped: " + result.getName());
ConstructorOrMethod consOrMethod = result.getMethod().getConstructorOrMethod();
DisableUIListeners disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableUIListeners.class);
if (disable != null) {
return;
}
driver = ((AbstractDriverBaseTest) result.getInstance()).getDriver();
captureScreen(driver, "skipped");
}
}

7
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java

@ -39,6 +39,13 @@ public class TestProperties {
return getProperties().getProperty("tb.baseUrl");
}
public static String getBaseUiUrl() {
if (instance.isActive()) {
return "https://host.docker.internal";
}
return getProperties().getProperty("tb.baseUrl");
}
public static String getWebSocketUrl() {
if (instance.isActive()) {
return WSS_URL;

80
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java

@ -26,8 +26,10 @@ import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.EntityId;
@ -78,7 +80,7 @@ public class TestRestClient {
loginRequest.put("password", password);
JsonPath jsonPath = given().spec(requestSpec).body(loginRequest)
.post( "/api/auth/login")
.post("/api/auth/login")
.getBody().jsonPath();
token = jsonPath.get("token");
refreshToken = jsonPath.get("refreshToken");
@ -86,7 +88,7 @@ public class TestRestClient {
}
public Device postDevice(String accessToken, Device device) {
return given().spec(requestSpec).body(device)
return given().spec(requestSpec).body(device)
.pathParams("accessToken", accessToken)
.post("/api/device?accessToken={accessToken}")
.then()
@ -105,62 +107,65 @@ public class TestRestClient {
}
public ValidatableResponse getDeviceById(DeviceId deviceId, int statusCode) {
return given().spec(requestSpec)
return given().spec(requestSpec)
.pathParams("deviceId", deviceId.getId())
.get("/api/device/{deviceId}")
.then()
.statusCode(statusCode);
}
public Device getDeviceById(DeviceId deviceId) {
return getDeviceById(deviceId, HTTP_OK)
return getDeviceById(deviceId, HTTP_OK)
.extract()
.as(Device.class);
}
public DeviceCredentials getDeviceCredentialsByDeviceId(DeviceId deviceId) {
return given().spec(requestSpec).get("/api/device/{deviceId}/credentials", deviceId.getId())
.then()
.assertThat()
.statusCode(HTTP_OK)
.extract()
.as(DeviceCredentials.class);
.then()
.assertThat()
.statusCode(HTTP_OK)
.extract()
.as(DeviceCredentials.class);
}
public ValidatableResponse postTelemetry(String credentialsId, JsonNode telemetry) {
return given().spec(requestSpec).body(telemetry)
.post("/api/v1/{credentialsId}/telemetry", credentialsId)
.then()
.statusCode(HTTP_OK);
return given().spec(requestSpec).body(telemetry)
.post("/api/v1/{credentialsId}/telemetry", credentialsId)
.then()
.statusCode(HTTP_OK);
}
public ValidatableResponse deleteDevice(DeviceId deviceId) {
return given().spec(requestSpec)
return given().spec(requestSpec)
.delete("/api/device/{deviceId}", deviceId.getId())
.then()
.statusCode(HTTP_OK);
}
public ValidatableResponse deleteDeviceIfExists(DeviceId deviceId) {
return given().spec(requestSpec)
return given().spec(requestSpec)
.delete("/api/device/{deviceId}", deviceId.getId())
.then()
.statusCode(anyOf(is(HTTP_OK),is(HTTP_NOT_FOUND)));
.statusCode(anyOf(is(HTTP_OK), is(HTTP_NOT_FOUND)));
}
public ValidatableResponse postTelemetryAttribute(String entityType, DeviceId deviceId, String scope, JsonNode attribute) {
return given().spec(requestSpec).body(attribute)
return given().spec(requestSpec).body(attribute)
.post("/api/plugins/telemetry/{entityType}/{entityId}/attributes/{scope}", entityType, deviceId.getId(), scope)
.then()
.statusCode(HTTP_OK);
}
public ValidatableResponse postAttribute(String accessToken, JsonNode attribute) {
return given().spec(requestSpec).body(attribute)
return given().spec(requestSpec).body(attribute)
.post("/api/v1/{accessToken}/attributes/", accessToken)
.then()
.statusCode(HTTP_OK);
}
public JsonNode getAttributes(String accessToken, String clientKeys, String sharedKeys) {
return given().spec(requestSpec)
return given().spec(requestSpec)
.queryParam("clientKeys", clientKeys)
.queryParam("sharedKeys", sharedKeys)
.get("/api/v1/{accessToken}/attributes", accessToken)
@ -186,10 +191,11 @@ public class TestRestClient {
.then()
.statusCode(HTTP_OK)
.extract()
.as(new TypeRef<PageData<RuleChain>>() {});
.as(new TypeRef<PageData<RuleChain>>() {
});
}
public RuleChain postRootRuleChain(RuleChain ruleChain) {
public RuleChain postRuleChain(RuleChain ruleChain) {
return given().spec(requestSpec)
.body(ruleChain)
.post("/api/ruleChain")
@ -258,7 +264,8 @@ public class TestRestClient {
.then()
.statusCode(HTTP_OK)
.extract()
.as(new TypeRef<List<EntityRelation>>() {});
.as(new TypeRef<List<EntityRelation>>() {
});
}
public JsonNode postServerSideRpc(DeviceId deviceId, JsonNode serverRpcPayload) {
@ -289,6 +296,35 @@ public class TestRestClient {
.as(DeviceProfile.class);
}
public Customer postCustomer(Customer customer) {
return given().spec(requestSpec)
.body(customer)
.post("/api/customer")
.then()
.statusCode(HTTP_OK)
.extract()
.as(Customer.class);
}
public void deleteCustomer(CustomerId customerId) {
given().spec(requestSpec)
.delete("/api/customer/{customerId}", customerId.getId())
.then()
.statusCode(HTTP_OK);
}
public PageData<Customer> getCustomers(PageLink pageLink) {
Map<String, String> params = new HashMap<>();
addPageLinkToParam(params, pageLink);
return given().spec(requestSpec).queryParams(params)
.get("/api/customers")
.then()
.statusCode(HTTP_OK)
.extract()
.as(new TypeRef<PageData<Customer>>() {
});
}
public String getToken() {
return token;
}

3
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java

@ -18,7 +18,6 @@ package org.thingsboard.server.msa.connectivity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.gson.JsonObject;
import io.restassured.path.json.JsonPath;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@ -29,11 +28,13 @@ import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.msg.session.FeatureType;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.DisableUIListeners;
import org.thingsboard.server.msa.TestCoapClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype;
@DisableUIListeners
public class CoapClientTest extends AbstractContainerTest {
private TestCoapClient client;

2
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java

@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.DisableUIListeners;
import org.thingsboard.server.msa.WsClient;
import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
@ -37,6 +38,7 @@ import static org.thingsboard.server.common.data.DataConstants.DEVICE;
import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE;
import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype;
@DisableUIListeners
public class HttpClientTest extends AbstractContainerTest {
private Device device;
@BeforeMethod

4
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java

@ -46,6 +46,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.DisableUIListeners;
import org.thingsboard.server.msa.WsClient;
import org.thingsboard.server.msa.mapper.AttributesResponse;
import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
@ -68,6 +69,7 @@ import static org.thingsboard.server.common.data.DataConstants.DEVICE;
import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE;
import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype;
@DisableUIListeners
@Slf4j
public class MqttClientTest extends AbstractContainerTest {
@ -426,7 +428,7 @@ public class MqttClientTest extends AbstractContainerTest {
RuleChain newRuleChain = new RuleChain();
newRuleChain.setName("testRuleChain");
RuleChain ruleChain = testRestClient.postRootRuleChain(newRuleChain);
RuleChain ruleChain = testRestClient.postRuleChain(newRuleChain);
JsonNode configuration = mapper.readTree(this.getClass().getClassLoader().getResourceAsStream("RpcResponseRuleChainMetadata.json"));
RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();

2
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java

@ -46,6 +46,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.DisableUIListeners;
import org.thingsboard.server.msa.WsClient;
import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
@ -66,6 +67,7 @@ import static org.thingsboard.server.common.data.DataConstants.DEVICE;
import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE;
import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultGatewayPrototype;
@DisableUIListeners
@Slf4j
public class MqttGatewayClientTest extends AbstractContainerTest {
private Device gatewayDevice;

143
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/base/AbstractBasePage.java

@ -0,0 +1,143 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.base;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Slf4j
abstract public class AbstractBasePage {
protected WebDriver driver;
protected WebDriverWait wait;
protected Actions actions;
public AbstractBasePage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofMillis(5000));
this.actions = new Actions(driver);
}
@SneakyThrows
protected static void sleep(double second) {
Thread.sleep((long) (second * 1000L));
}
protected WebElement waitUntilVisibilityOfElementLocated(String locator) {
try {
return wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator)));
} catch (WebDriverException e) {
log.error("No visibility element: " + locator);
return null;
}
}
protected WebElement waitUntilElementToBeClickable(String locator) {
try {
return wait.until(ExpectedConditions.elementToBeClickable(By.xpath(locator)));
} catch (WebDriverException e) {
log.error("No clickable element: " + locator);
return null;
}
}
protected List<WebElement> waitUntilVisibilityOfElementsLocated(String locator) {
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator)));
return driver.findElements(By.xpath(locator));
} catch (WebDriverException e) {
log.error("No visibility elements: " + locator);
return null;
}
}
protected List<WebElement> waitUntilElementsToBeClickable(String locator) {
try {
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(locator)));
return driver.findElements(By.xpath(locator));
} catch (WebDriverException e) {
log.error("No clickable elements: " + locator);
return null;
}
}
public void waitUntilUrlContainsText(String urlPath) {
try {
wait.until(ExpectedConditions.urlContains(urlPath));
} catch (WebDriverException e) {
log.error("This URL path is missing");
}
}
protected void moveCursor(WebElement element) {
actions.moveToElement(element).perform();
}
protected void doubleClick(WebElement element) {
actions.doubleClick(element).build().perform();
}
public boolean elementIsNotPresent(String locator) {
try {
return wait.until(ExpectedConditions.not(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))));
} catch (WebDriverException e) {
throw new AssertionError("Element is present");
}
}
public boolean elementsIsNotPresent(String locator) {
try {
return wait.until(ExpectedConditions.not(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath(locator))));
} catch (WebDriverException e) {
throw new AssertionError("Elements is present");
}
}
public void waitUntilNumberOfTabToBe(int tabNumber) {
try {
wait.until(ExpectedConditions.numberOfWindowsToBe(tabNumber));
} catch (WebDriverException e) {
log.error("No tabs with this number");
}
}
public void goToNextTab(int tabNumber) {
waitUntilNumberOfTabToBe(tabNumber);
ArrayList<String> tabs = new ArrayList<>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(tabNumber - 1));
}
public static long getRandomNumber() {
return System.currentTimeMillis();
}
public static char getRandomSymbol() {
Random rand = new Random();
String s = "~`!@#$^&*()_+=-";
return s.charAt(rand.nextInt(s.length()));
}
}

123
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/base/AbstractDriverBaseTest.java

@ -0,0 +1,123 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.base;
import com.google.common.io.Files;
import io.github.bonigarcia.wdm.WebDriverManager;
import io.qameta.allure.Attachment;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.ContainerTestSuite;
import java.io.File;
import java.net.URL;
import java.time.Duration;
import java.util.stream.Collectors;
import static org.thingsboard.server.msa.TestProperties.getBaseUiUrl;
@Slf4j
abstract public class AbstractDriverBaseTest extends AbstractContainerTest {
protected WebDriver driver;
private final Dimension dimension = new Dimension(WIDTH, HEIGHT);
private static final int WIDTH = 1680;
private static final int HEIGHT = 1050;
private static final String REMOTE_WEBDRIVER_HOST = "http://localhost:4444";
protected static final PageLink pageLink = new PageLink(10);
private static final ContainerTestSuite instance = ContainerTestSuite.getInstance();
@SneakyThrows
@BeforeMethod
public void openBrowser() {
log.info("===>>> Setup driver");
ChromeOptions options = new ChromeOptions();
options.setAcceptInsecureCerts(true);
if (instance.isActive()) {
RemoteWebDriver remoteWebDriver = new RemoteWebDriver(new URL(REMOTE_WEBDRIVER_HOST), options);
remoteWebDriver.setFileDetector(new LocalFileDetector());
driver = remoteWebDriver;
} else {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver(options);
}
driver.manage().window().setSize(dimension);
}
@AfterMethod
public void closeBrowser() {
log.info("<<<=== Teardown");
driver.quit();
}
public void openLocalhost() {
driver.get(getBaseUiUrl());
}
public String getUrl() {
return driver.getCurrentUrl();
}
public WebDriver getDriver() {
return driver;
}
protected boolean urlContains(String urlPath) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(5000));
try {
wait.until(ExpectedConditions.urlContains(urlPath));
} catch (WebDriverException e) {
log.error("This URL path is missing");
}
return driver.getCurrentUrl().contains(urlPath);
}
public static RuleChain getRuleChainByName(String name) {
return testRestClient.getRuleChains(pageLink).getData().stream()
.filter(s -> s.getName().equals(name)).collect(Collectors.toList()).get(0);
}
public static Customer getCustomerByName(String name) {
return testRestClient.getCustomers(pageLink).getData().stream()
.filter(x -> x.getName().equals(name)).collect(Collectors.toList()).get(0);
}
@SneakyThrows
@Attachment(value = "Page screenshot", type = "image/png")
public static byte[] captureScreen(WebDriver driver, String dirPath) {
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("./target/allure-results/screenshots/" + dirPath + "//" + screenshot.getName()));
return Files.toByteArray(screenshot);
}
}

42
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/listeners/RetryAnalyzer.java

@ -0,0 +1,42 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.listeners;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.internal.ConstructorOrMethod;
import org.thingsboard.server.msa.DisableUIListeners;
public class RetryAnalyzer implements IRetryAnalyzer {
private int retryCount = 0;
private static final int MAX_RETRY_COUNT = 2;
@Override
public boolean retry(ITestResult result) {
ConstructorOrMethod consOrMethod = result.getMethod().getConstructorOrMethod();
DisableUIListeners disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableUIListeners.class);
if (disable != null) {
return false;
}
if (retryCount < MAX_RETRY_COUNT) {
System.out.printf("Retrying test %s for the %d time(s).%n", result.getName(), retryCount + 1);
retryCount++;
return true;
}
return false;
}
}

33
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/listeners/RetryTestListener.java

@ -0,0 +1,33 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.listeners;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class RetryTestListener implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation,
Class testClass,
Constructor testConstructor,
Method testMethod) {
annotation.setRetryAnalyzer(RetryAnalyzer.class);
}
}

282
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CustomerPageElements.java

@ -0,0 +1,282 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.util.List;
public class CustomerPageElements extends OtherPageElementsHelper {
public CustomerPageElements(WebDriver driver) {
super(driver);
}
private static final String CUSTOMER = "//mat-row//span[contains(text(),'%s')]";
private static final String EMAIL = ENTITY + "/../..//mat-cell[contains(@class,'email')]/span";
private static final String COUNTRY = ENTITY + "/../..//mat-cell[contains(@class,'country')]/span";
private static final String CITY = ENTITY + "/../..//mat-cell[contains(@class,'city')]/span";
private static final String TITLES = "//mat-cell[contains(@class,'cdk-column-title')]/span";
protected static final String EDIT_MENU_DASHBOARD_FIELD = "//input[@formcontrolname='dashboard']";
private static final String EDIT_MENU_DASHBOARD = "//div[@class='cdk-overlay-pane']//span/span";
private static final String MANAGE_CUSTOMERS_USERS_BTN = ENTITY + "/../..//mat-icon[contains(text(),' account_circle')]/../..";
private static final String MANAGE_CUSTOMERS_ASSETS_BTN = ENTITY + "/../..//mat-icon[contains(text(),' domain')]/../..";
private static final String MANAGE_CUSTOMERS_DEVICES_BTN = ENTITY + "/../..//mat-icon[contains(text(),' devices_other')]/../..";
private static final String MANAGE_CUSTOMERS_DASHBOARDS_BTN = ENTITY + "/../..//mat-icon[contains(text(),' dashboard')]/../..";
private static final String MANAGE_CUSTOMERS_EDGE_BTN = ENTITY + "/../..//mat-icon[contains(text(),' router')]/../..";
private static final String ADD_USER_EMAIL = "//tb-add-user-dialog//input[@formcontrolname='email']";
private static final String ACTIVATE_WINDOW_OK_BTN = "//span[contains(text(),'OK')]";
private static final String USER_LOGIN_BTN = "//mat-icon[@data-mat-icon-name='login']";
private static final String USERS_WIDGET = "//tb-widget";
private static final String SELECT_COUNTRY_MENU = "//mat-form-field//mat-select[@formcontrolname='country']";
private static final String COUNTRIES = "//span[@class='mat-option-text']";
protected static final String INPUT_FIELD = "//input[@formcontrolname='%s']";
protected static final String INPUT_FIELD_NAME_TITLE = "title";
private static final String INPUT_FIELD_NAME_CITY = "city";
private static final String INPUT_FIELD_NAME_STATE = "state";
private static final String INPUT_FIELD_NAME_ZIP = "zip";
private static final String INPUT_FIELD_NAME_ADDRESS = "address";
private static final String INPUT_FIELD_NAME_ADDRESS2 = "address2";
private static final String INPUT_FIELD_NAME_EMAIL = "email";
private static final String INPUT_FIELD_NAME_NUMBER = "phoneNumber";
private static final String INPUT_FIELD_NAME_ASSIGNED_LIST = "entity";
private static final String ASSIGNED_BTN = "//button[@type='submit']";
private static final String HIDE_HOME_DASHBOARD_TOOLBAR = "//mat-checkbox[@formcontrolname='homeDashboardHideToolbar']/label";
private static final String FILTER_BTN = "//tb-filters-edit";
private static final String TIME_BTN = "//tb-timewindow";
private static final String CUSTOMER_ICON_HEADER = "//tb-breadcrumb//span[contains(text(),'Customer %s')]";
private static final String CUSTOMER_USER_ICON_HEADER = "Users";
private static final String CUSTOMER_ASSETS_ICON_HEADER = "Assets";
private static final String CUSTOMER_DEVICES_ICON_HEADER = "Devices";
private static final String CUSTOMER_DASHBOARD_ICON_HEADER = "Dashboards";
private static final String CUSTOMER_EDGE_ICON_HEADER = "edge instances";
private static final String CUSTOMER_USER_ICON_HEAD = "(//mat-drawer-content//span[contains(@class,'tb-entity-table')])[1]";
private static final String MANAGE_BTN_VIEW = "//span[contains(text(),'%s')]";
private static final String MANAGE_CUSTOMERS_USERS_BTN_VIEW = "Manage users";
private static final String MANAGE_CUSTOMERS_ASSETS_BTN_VIEW = "Manage assets";
private static final String MANAGE_CUSTOMERS_DEVICE_BTN_VIEW = "Manage devices";
private static final String MANAGE_CUSTOMERS_DASHBOARD_BTN_VIEW = "Manage dashboards";
private static final String MANAGE_CUSTOMERS_EDGE_BTN_VIEW = "Manage edges ";
private static final String DELETE_FROM_VIEW_BTN = "//tb-customer//span[contains(text(),' Delete')]";
public WebElement titleFieldAddEntityView() {
return waitUntilElementToBeClickable(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_TITLE));
}
public WebElement titleFieldEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_TITLE));
}
public WebElement customer(String entityName) {
return waitUntilElementToBeClickable(String.format(CUSTOMER, entityName));
}
public WebElement email(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(EMAIL, entityName));
}
public WebElement country(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(COUNTRY, entityName));
}
public WebElement city(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(CITY, entityName));
}
public List<WebElement> entityTitles() {
return waitUntilVisibilityOfElementsLocated(TITLES);
}
public WebElement editMenuDashboardField() {
return waitUntilVisibilityOfElementLocated(EDIT_MENU_DASHBOARD_FIELD);
}
public WebElement editMenuDashboard() {
return waitUntilElementToBeClickable(EDIT_MENU_DASHBOARD);
}
public WebElement phoneNumberEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_NUMBER));
}
public WebElement phoneNumberAddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_NUMBER));
}
public WebElement manageCustomersUserBtn(String title) {
return waitUntilElementToBeClickable(String.format(MANAGE_CUSTOMERS_USERS_BTN, title));
}
public WebElement manageCustomersAssetsBtn(String title) {
return waitUntilElementToBeClickable(String.format(MANAGE_CUSTOMERS_ASSETS_BTN, title));
}
public WebElement manageCustomersDevicesBtn(String title) {
return waitUntilElementToBeClickable(String.format(MANAGE_CUSTOMERS_DEVICES_BTN, title));
}
public WebElement manageCustomersDashboardsBtn(String title) {
return waitUntilElementToBeClickable(String.format(MANAGE_CUSTOMERS_DASHBOARDS_BTN, title));
}
public WebElement manageCustomersEdgeBtn(String title) {
return waitUntilElementToBeClickable(String.format(MANAGE_CUSTOMERS_EDGE_BTN, title));
}
public WebElement addUserEmailField() {
return waitUntilElementToBeClickable(ADD_USER_EMAIL);
}
public WebElement activateWindowOkBtn() {
return waitUntilElementToBeClickable(ACTIVATE_WINDOW_OK_BTN);
}
public WebElement userLoginBtn() {
return waitUntilElementToBeClickable(USER_LOGIN_BTN);
}
public WebElement usersWidget() {
return waitUntilVisibilityOfElementLocated(USERS_WIDGET);
}
public WebElement countrySelectMenuEntityView() {
return waitUntilElementToBeClickable(SELECT_COUNTRY_MENU);
}
public WebElement countrySelectMenuAddEntityView() {
return waitUntilElementToBeClickable(ADD_ENTITY_VIEW + SELECT_COUNTRY_MENU);
}
public List<WebElement> countries() {
return waitUntilElementsToBeClickable(COUNTRIES);
}
public WebElement cityEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_CITY));
}
public WebElement cityAddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_CITY));
}
public WebElement stateEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_STATE));
}
public WebElement stateAddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_STATE));
}
public WebElement zipEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_ZIP));
}
public WebElement zipAddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_ZIP));
}
public WebElement addressEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_ADDRESS));
}
public WebElement addressAddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_ADDRESS));
}
public WebElement address2EntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_ADDRESS2));
}
public WebElement address2AddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_ADDRESS2));
}
public WebElement emailEntityView() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_EMAIL));
}
public WebElement emailAddEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW + String.format(INPUT_FIELD, INPUT_FIELD_NAME_EMAIL));
}
public WebElement assignedField() {
return waitUntilVisibilityOfElementLocated(String.format(INPUT_FIELD, INPUT_FIELD_NAME_ASSIGNED_LIST));
}
public WebElement submitAssignedBtn() {
return waitUntilElementToBeClickable(ASSIGNED_BTN);
}
public WebElement hideHomeDashboardToolbarCheckbox() {
return waitUntilElementToBeClickable(HIDE_HOME_DASHBOARD_TOOLBAR);
}
public WebElement filterBtn() {
return waitUntilVisibilityOfElementLocated(FILTER_BTN);
}
public WebElement timeBtn() {
return waitUntilVisibilityOfElementLocated(TIME_BTN);
}
public WebElement customerUserIconHeader() {
return waitUntilVisibilityOfElementLocated(String.format(CUSTOMER_ICON_HEADER, CUSTOMER_USER_ICON_HEADER));
}
public WebElement customerAssetsIconHeader() {
return waitUntilVisibilityOfElementLocated(String.format(CUSTOMER_ICON_HEADER, CUSTOMER_ASSETS_ICON_HEADER));
}
public WebElement customerDevicesIconHeader() {
return waitUntilVisibilityOfElementLocated(String.format(CUSTOMER_ICON_HEADER, CUSTOMER_DEVICES_ICON_HEADER));
}
public WebElement customerDashboardIconHeader() {
return waitUntilVisibilityOfElementLocated(String.format(CUSTOMER_ICON_HEADER, CUSTOMER_DASHBOARD_ICON_HEADER));
}
public WebElement customerEdgeIconHeader() {
return waitUntilVisibilityOfElementLocated(String.format(CUSTOMER_ICON_HEADER, CUSTOMER_EDGE_ICON_HEADER));
}
public WebElement customerManageWindowIconHead() {
return waitUntilVisibilityOfElementLocated(CUSTOMER_USER_ICON_HEAD);
}
public WebElement manageCustomersUserBtnView() {
return waitUntilElementToBeClickable(String.format(MANAGE_BTN_VIEW, MANAGE_CUSTOMERS_USERS_BTN_VIEW));
}
public WebElement manageCustomersAssetsBtnView() {
return waitUntilElementToBeClickable(String.format(MANAGE_BTN_VIEW, MANAGE_CUSTOMERS_ASSETS_BTN_VIEW));
}
public WebElement manageCustomersDeviceBtnView() {
return waitUntilElementToBeClickable(String.format(MANAGE_BTN_VIEW, MANAGE_CUSTOMERS_DEVICE_BTN_VIEW));
}
public WebElement manageCustomersDashboardsBtnView() {
return waitUntilElementToBeClickable(String.format(MANAGE_BTN_VIEW, MANAGE_CUSTOMERS_DASHBOARD_BTN_VIEW));
}
public WebElement manageCustomersEdgeBtnView() {
return waitUntilElementToBeClickable(String.format(MANAGE_BTN_VIEW, MANAGE_CUSTOMERS_EDGE_BTN_VIEW));
}
public WebElement customerViewDeleteBtn() {
return waitUntilElementToBeClickable(DELETE_FROM_VIEW_BTN);
}
}

145
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CustomerPageHelper.java

@ -0,0 +1,145 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
@Slf4j
public class CustomerPageHelper extends CustomerPageElements {
public CustomerPageHelper(WebDriver driver) {
super(driver);
}
private String customerName;
private String country;
private String dashboard;
private String dashboardFromView;
private String customerEmail;
private String customerCountry;
private String customerCity;
public void setCustomerName() {
this.customerName = entityTitles().get(0).getText();
}
public void setCustomerName(int number) {
this.customerName = entityTitles().get(number).getText();
}
public String getCustomerName() {
return customerName;
}
public void setCountry() {
this.country = countries().get(0).getText();
}
public String getCountry() {
return country;
}
public void setDashboard() {
this.dashboard = listOfEntity().get(0).getText();
}
public void setDashboardFromView() {
this.dashboardFromView = editMenuDashboardField().getAttribute("value");
}
public String getDashboard() {
return dashboard;
}
public String getDashboardFromView() {
return dashboardFromView;
}
public void setCustomerEmail(String title) {
this.customerEmail = email(title).getText();
}
public String getCustomerEmail() {
return customerEmail;
}
public void setCustomerCountry(String title) {
this.customerCountry = country(title).getText();
}
public String getCustomerCountry() {
return customerCountry;
}
public void setCustomerCity(String title) {
this.customerCity = city(title).getText();
}
public String getCustomerCity() {
return customerCity;
}
public void changeTitleEditMenu(String newTitle) {
titleFieldEntityView().clear();
wait.until(ExpectedConditions.textToBe(By.xpath(String.format(INPUT_FIELD, INPUT_FIELD_NAME_TITLE)), ""));
titleFieldEntityView().sendKeys(newTitle);
}
public void chooseDashboard() {
editMenuDashboardField().click();
sleep(0.5);
editMenuDashboard().click();
sleep(0.5);
}
public void createCustomersUser() {
plusBtn().click();
addUserEmailField().sendKeys(getRandomNumber() + "@gmail.com");
addBtnC().click();
activateWindowOkBtn().click();
}
public void selectCountryEntityView() {
countrySelectMenuEntityView().click();
setCountry();
countries().get(0).click();
}
public void selectCountryAddEntityView() {
countrySelectMenuAddEntityView().click();
setCountry();
countries().get(0).click();
}
public void assignedDashboard() {
plusBtn().click();
assignedField().click();
setDashboard();
listOfEntity().get(0).click();
submitAssignedBtn().click();
}
public boolean customerIsNotPresent(String title) {
return elementsIsNotPresent(getEntity(title));
}
public void sortByNameDown() {
doubleClick(sortByTitleBtn());
}
}

53
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DashboardPageElements.java

@ -0,0 +1,53 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.util.List;
public class DashboardPageElements extends OtherPageElementsHelper {
public DashboardPageElements(WebDriver driver) {
super(driver);
}
private static final String TITLES = "//mat-cell[contains(@class,'cdk-column-title')]/span";
private static final String ASSIGNED_BTN = ENTITY + "/../..//mat-icon[contains(text(),' assignment_ind')]/../..";
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_UPDATE_BTN = "//button[@type='submit']";
public List<WebElement> entityTitles() {
return waitUntilVisibilityOfElementsLocated(TITLES);
}
public WebElement assignedBtn(String title) {
return waitUntilElementToBeClickable(String.format(ASSIGNED_BTN, title));
}
public WebElement manageAssignedEntityListField() {
return waitUntilElementToBeClickable(MANAGE_ASSIGNED_ENTITY_LIST_FIELD);
}
public WebElement manageAssignedEntity(String title) {
return waitUntilElementToBeClickable(String.format(MANAGE_ASSIGNED_ENTITY, title));
}
public WebElement manageAssignedUpdateBtn() {
return waitUntilElementToBeClickable(MANAGE_ASSIGNED_UPDATE_BTN);
}
}

40
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DashboardPageHelper.java

@ -0,0 +1,40 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
public class DashboardPageHelper extends DashboardPageElements {
public DashboardPageHelper(WebDriver driver) {
super(driver);
}
private String dashboardTitle;
public void setDashboardTitle() {
this.dashboardTitle = entityTitles().get(0).getText();
}
public String getDashboardTitle() {
return dashboardTitle;
}
public void assignedCustomer(String title) {
manageAssignedEntityListField().click();
manageAssignedEntity(title).click();
manageAssignedUpdateBtn().click();
}
}

43
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/LoginPageElements.java

@ -0,0 +1,43 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.thingsboard.server.msa.ui.base.AbstractBasePage;
public class LoginPageElements extends AbstractBasePage {
public LoginPageElements(WebDriver driver) {
super(driver);
}
private static final String EMAIL_FIELD = "//input[@id='username-input']";
private static final String PASSWORD_FIELD = "//input[@id='password-input']";
private static final String SUBMIT_BTN = "//button[@type='submit']";
public WebElement emailField() {
return waitUntilElementToBeClickable(EMAIL_FIELD);
}
public WebElement passwordField() {
return waitUntilElementToBeClickable(PASSWORD_FIELD);
}
public WebElement submitBtn() {
return waitUntilElementToBeClickable(SUBMIT_BTN);
}
}

31
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/LoginPageHelper.java

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.thingsboard.server.msa.ui.utils.Const;
public class LoginPageHelper extends LoginPageElements {
public LoginPageHelper(WebDriver driver) {
super(driver);
}
public void authorizationTenant() {
emailField().sendKeys(Const.TENANT_EMAIL);
passwordField().sendKeys(Const.TENANT_PASSWORD);
submitBtn().click();
}
}

48
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OpenRuleChainPageElements.java

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.thingsboard.server.msa.ui.base.AbstractBasePage;
public class OpenRuleChainPageElements extends AbstractBasePage {
public OpenRuleChainPageElements(WebDriver driver) {
super(driver);
}
private static final String DONE_BTN = "//mat-icon[contains(text(),'done')]/../..";
private static final String DONE_BTN_DISABLE = "//mat-icon[contains(text(),'done')]/../parent::button[@disabled='true']";
private static final String INPUT_NODE = "//div[@class='tb-rule-node tb-input-type']";
private static final String HEAD_RULE_CHAIN_NAME = "//div[@class='tb-breadcrumb']/span[2]";
public WebElement inputNode() {
return waitUntilVisibilityOfElementLocated(INPUT_NODE);
}
public WebElement headRuleChainName() {
return waitUntilVisibilityOfElementLocated(HEAD_RULE_CHAIN_NAME);
}
public String getDoneBtnDisable() {
return DONE_BTN_DISABLE;
}
public WebElement doneBtn() {
return waitUntilElementToBeClickable(DONE_BTN);
}
}

38
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OpenRuleChainPageHelper.java

@ -0,0 +1,38 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
public class OpenRuleChainPageHelper extends OpenRuleChainPageElements {
public OpenRuleChainPageHelper(WebDriver driver) {
super(driver);
}
private String headName;
public void setHeadName() {
this.headName = headRuleChainName().getText().split(" ")[1];
}
public String getHeadName() {
return headName;
}
public void waitUntilDoneBtnDisable() {
waitUntilVisibilityOfElementLocated(getDoneBtnDisable());
}
}

249
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OtherPageElements.java

@ -0,0 +1,249 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.thingsboard.server.msa.ui.base.AbstractBasePage;
import java.util.List;
public class OtherPageElements extends AbstractBasePage {
public OtherPageElements(WebDriver driver) {
super(driver);
}
protected static final String ENTITY = "//mat-row//span[contains(text(),'%s')]";
protected static final String DELETE_BTN = ENTITY + "/../..//mat-icon[contains(text(),' delete')]/../..";
protected static final String DETAILS_BTN = ENTITY + "/../..//mat-icon[contains(text(),'edit')]/../..";
private static final String ENTITY_COUNT = "//div[@class='mat-paginator-range-label']";
private static final String WARNING_DELETE_POPUP_YES = "//tb-confirm-dialog//button[2]";
private static final String WARNING_DELETE_POPUP_TITLE = "//tb-confirm-dialog/h2";
private static final String REFRESH_BTN = "//mat-icon[contains(text(),'refresh')]/..";
private static final String HELP_BTN = "//mat-icon[contains(text(),'help')]/..";
private static final String CHECKBOX = "//mat-row//span[contains(text(),'%s')]/../..//mat-checkbox";
private static final String CHECKBOXES = "//tbody//mat-checkbox";
private static final String DELETE_SELECTED_BTN = "//span[contains(text(),'selected')]//..//mat-icon/../..";
private static final String DELETE_BTNS = "//mat-icon[contains(text(),' delete')]/../..";
private static final String MARKS_CHECKBOX = "//mat-row[contains (@class,'mat-selected')]//mat-checkbox[contains(@class, 'checked')]";
private static final String SELECT_ALL_CHECKBOX = "//thead//mat-checkbox";
private static final String ALL_ENTITY = "//mat-row[@class='mat-row cdk-row mat-row-select ng-star-inserted']";
private static final String EDIT_PENCIL_BTN = "//mat-icon[contains(text(),'edit')]/ancestor::button";
private static final String NAME_FIELD_EDIT_VIEW = "//input[@formcontrolname='name']";
private static final String HEADER_NAME_VIEW = "//header//div[@class='tb-details-title']/span";
private static final String DONE_BTN_EDIT_VIEW = "//mat-icon[contains(text(),'done')]/ancestor::button";
private static final String DESCRIPTION_ENTITY_VIEW = "//textarea";
private static final String DESCRIPTION_ADD_ENTITY_VIEW = "//tb-add-entity-dialog//textarea";
private static final String DEBUG_CHECKBOX_EDIT = "//mat-checkbox[@formcontrolname='debugMode']";
private static final String DEBUG_CHECKBOX_VIEW = "//mat-checkbox[@formcontrolname='debugMode']//input";
private static final String CLOSE_ENTITY_VIEW_BTN = "//header//mat-icon[contains(text(),'close')]/../..";
private static final String SEARCH_BTN = "//mat-toolbar//mat-icon[contains(text(),'search')]/.." +
"/parent::button[@class='mat-focus-indicator mat-tooltip-trigger mat-icon-button mat-button-base ng-star-inserted']";
private static final String SORT_BY_NAME_BTN = "//div[contains(text(),'Name')]";
private static final String SORT_BY_TITLE_BTN = "//div[contains(text(),'Title')]";
private static final String SORT_BY_TIME_BTN = "//div[contains(text(),'Created time')]/..";
private static final String CREATED_TIME = "//tbody[@role='rowgroup']//mat-cell[2]/span";
private static final String PLUS_BTN = "//mat-icon[contains(text(),'add')]/../parent::button";
private static final String CREATE_VIEW_ADD_BTN = "//span[contains(text(),'Add')]/..";
private static final String WARNING_MESSAGE = "//tb-snack-bar-component/div/div";
private static final String ERROR_MESSAGE = "//mat-error";
private static final String ENTITY_VIEW_TITLE = "//div[@class='tb-details-title']//span";
private static final String LIST_OF_ENTITY = "//div[@role='listbox']/mat-option";
protected static final String ADD_ENTITY_VIEW = "//tb-add-entity-dialog";
protected static final String STATE_CONTROLLER = "//tb-entity-state-controller";
private static final String SEARCH_FIELD = "//input[contains (@data-placeholder,'Search')]";
public String getEntity(String entityName) {
return String.format(ENTITY, entityName);
}
public String getWarningMessage() {
return WARNING_MESSAGE;
}
public String getDeleteBtns() {
return DELETE_BTNS;
}
public String getCheckbox(String entityName) {
return String.format(CHECKBOX, entityName);
}
public String getCheckboxes() {
return String.format(CHECKBOXES);
}
public WebElement warningPopUpYesBtn() {
return waitUntilElementToBeClickable(WARNING_DELETE_POPUP_YES);
}
public WebElement warningPopUpTitle() {
return waitUntilElementToBeClickable(WARNING_DELETE_POPUP_TITLE);
}
public WebElement entityCount() {
return waitUntilVisibilityOfElementLocated(ENTITY_COUNT);
}
public WebElement refreshBtn() {
return waitUntilElementToBeClickable(REFRESH_BTN);
}
public WebElement helpBtn() {
return waitUntilElementToBeClickable(HELP_BTN);
}
public WebElement checkBox(String entityName) {
return waitUntilElementToBeClickable(String.format(CHECKBOX, entityName));
}
public WebElement deleteSelectedBtn() {
return waitUntilElementToBeClickable(DELETE_SELECTED_BTN);
}
public WebElement selectAllCheckBox() {
return waitUntilElementToBeClickable(SELECT_ALL_CHECKBOX);
}
public WebElement editPencilBtn() {
waitUntilVisibilityOfElementsLocated(EDIT_PENCIL_BTN);
return waitUntilElementToBeClickable(EDIT_PENCIL_BTN);
}
public WebElement nameFieldEditMenu() {
return waitUntilElementToBeClickable(NAME_FIELD_EDIT_VIEW);
}
public WebElement headerNameView() {
return waitUntilVisibilityOfElementLocated(HEADER_NAME_VIEW);
}
public WebElement doneBtnEditView() {
return waitUntilElementToBeClickable(DONE_BTN_EDIT_VIEW);
}
public WebElement descriptionEntityView() {
return waitUntilVisibilityOfElementLocated(DESCRIPTION_ENTITY_VIEW);
}
public WebElement descriptionAddEntityView() {
return waitUntilVisibilityOfElementLocated(DESCRIPTION_ADD_ENTITY_VIEW);
}
public WebElement debugCheckboxEdit() {
return waitUntilElementToBeClickable(DEBUG_CHECKBOX_EDIT);
}
public WebElement debugCheckboxView() {
return waitUntilVisibilityOfElementLocated(DEBUG_CHECKBOX_VIEW);
}
public WebElement closeEntityViewBtn() {
return waitUntilElementToBeClickable(CLOSE_ENTITY_VIEW_BTN);
}
public WebElement searchBtn() {
return waitUntilElementToBeClickable(SEARCH_BTN);
}
public List<WebElement> deleteBtns() {
return waitUntilVisibilityOfElementsLocated(DELETE_BTNS);
}
public List<WebElement> checkBoxes() {
return waitUntilElementsToBeClickable(CHECKBOXES);
}
public List<WebElement> markCheckbox() {
return waitUntilVisibilityOfElementsLocated(MARKS_CHECKBOX);
}
public List<WebElement> allEntity() {
return waitUntilVisibilityOfElementsLocated(ALL_ENTITY);
}
public WebElement doneBtnEditViewVisible() {
return waitUntilVisibilityOfElementLocated(DONE_BTN_EDIT_VIEW);
}
public WebElement sortByNameBtn() {
return waitUntilElementToBeClickable(SORT_BY_NAME_BTN);
}
public WebElement sortByTitleBtn() {
return waitUntilElementToBeClickable(SORT_BY_TITLE_BTN);
}
public WebElement sortByTimeBtn() {
return waitUntilElementToBeClickable(SORT_BY_TIME_BTN);
}
public List<WebElement> createdTime() {
return waitUntilVisibilityOfElementsLocated(CREATED_TIME);
}
public WebElement plusBtn() {
return waitUntilElementToBeClickable(PLUS_BTN);
}
public WebElement addBtnC() {
return waitUntilElementToBeClickable(CREATE_VIEW_ADD_BTN);
}
public WebElement addBtnV() {
return waitUntilVisibilityOfElementLocated(CREATE_VIEW_ADD_BTN);
}
public WebElement warningMessage() {
return waitUntilVisibilityOfElementLocated(WARNING_MESSAGE);
}
public WebElement deleteBtn(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(DELETE_BTN, entityName));
}
public WebElement detailsBtn(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(DETAILS_BTN, entityName));
}
public WebElement entity(String entityName) {
return waitUntilElementToBeClickable(String.format(ENTITY, entityName));
}
public WebElement errorMessage() {
return waitUntilVisibilityOfElementLocated(ERROR_MESSAGE);
}
public WebElement entityViewTitle() {
return waitUntilVisibilityOfElementLocated(ENTITY_VIEW_TITLE);
}
public List<WebElement> listOfEntity() {
return waitUntilElementsToBeClickable(LIST_OF_ENTITY);
}
public WebElement addEntityView() {
return waitUntilVisibilityOfElementLocated(ADD_ENTITY_VIEW);
}
public WebElement stateController() {
return waitUntilVisibilityOfElementLocated(STATE_CONTROLLER);
}
public WebElement searchField() {
return waitUntilElementToBeClickable(SEARCH_FIELD);
}
}

113
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/OtherPageElementsHelper.java

@ -0,0 +1,113 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
public class OtherPageElementsHelper extends OtherPageElements {
public OtherPageElementsHelper(WebDriver driver) {
super(driver);
}
private String headerName;
public void setHeaderName() {
this.headerName = headerNameView().getText();
}
public String getHeaderName() {
return headerName;
}
public boolean entityIsNotPresent(String entityName) {
return elementIsNotPresent(getEntity(entityName));
}
public void goToHelpPage() {
helpBtn().click();
goToNextTab(2);
}
public void clickOnCheckBoxes(int count) {
for (int i = 0; i < count; i++) {
checkBoxes().get(i).click();
}
}
public void changeNameEditMenu(String newName) {
nameFieldEditMenu().sendKeys(Keys.CONTROL + "a" + Keys.BACK_SPACE);
nameFieldEditMenu().sendKeys(newName);
}
public void changeDescription(String newDescription) {
descriptionEntityView().sendKeys(Keys.CONTROL + "a" + Keys.BACK_SPACE);
descriptionEntityView().sendKeys(newDescription);
}
public String deleteRuleChainTrash(String entityName) {
String s = "";
if (deleteBtn(entityName) != null) {
deleteBtn(entityName).click();
warningPopUpYesBtn().click();
return entityName;
} else {
for (int i = 0; i < deleteBtns().size(); i++) {
if (deleteBtns().get(i).isEnabled()) {
deleteBtns().get(i).click();
warningPopUpYesBtn().click();
if (elementIsNotPresent(getWarningMessage())) {
s = driver.findElements(By.xpath(getDeleteBtns()
+ "/../../../mat-cell/following-sibling::mat-cell/following-sibling::mat-cell[contains(@class,'cdk-column-name')]/span")).get(i).getText();
break;
}
}
}
return s;
}
}
public String deleteSelected(String entityName) {
String s = "";
if (deleteBtn(entityName) != null) {
checkBox(entityName).click();
deleteSelectedBtn().click();
warningPopUpYesBtn().click();
return entityName;
} else {
for (int i = 0; i < checkBoxes().size(); i++) {
if (checkBoxes().get(i).isDisplayed()) {
s = driver.findElements(By.xpath(getCheckboxes() + "/../../mat-cell/following-sibling::mat-cell/following-sibling::mat-cell[contains(@class,'cdk-column-name')]/span")).get(i).getText();
checkBox(s).click();
deleteSelectedBtn().click();
warningPopUpYesBtn().click();
if (elementIsNotPresent(getWarningMessage())) {
break;
}
}
}
return s;
}
}
public void searchEntity(String namePath) {
searchBtn().click();
searchField().sendKeys(namePath);
sleep(0.5);
}
}

128
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/RuleChainsPageElements.java

@ -0,0 +1,128 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.util.List;
public class RuleChainsPageElements extends OtherPageElementsHelper {
public RuleChainsPageElements(WebDriver driver) {
super(driver);
}
private static final String MAKE_ROOT_BTN = ENTITY + "/../..//mat-icon[contains(text(),' flag')]/../..";
private static final String ROOT = ENTITY + "/../..//mat-icon[text() = 'check_box']";
private static final String ROOT_DISABLE = ENTITY + "/../..//mat-icon[text() = 'check_box_outline_blank']";
private static final String CREATED_TIME = ENTITY + "/../..//mat-cell/span[contains(text(),'%s')]";
private static final String CREATE_RULE_CHAIN_BTN = "//span[contains(text(),'Create new rule chain')]";
private static final String CREATE_RULE_CHAIN_NAME_FIELD = "//form[@class='ng-untouched ng-pristine ng-invalid']//input[@formcontrolname='name']";
private static final String RULE_CHAINS_NAMES_WITHOUT_ROOT = "//mat-icon[contains(text(),'check_box_outline_blank')]/../../../mat-cell[contains(@class,'name')]/span";
private static final String DELETE_RULE_CHAIN_FROM_VIEW_BTN = "//span[contains(text(),' Delete')]";
private static final String IMPORT_RULE_CHAIN_BTN = "//span[contains(text(),'Import rule chain')]";
private static final String BROWSE_FILE = "//input[@class='file-input']";
private static final String IMPORT_BROWSE_FILE = "//mat-dialog-container//span[contains(text(),'Import')]/..";
private static final String IMPORTING_FILE = "//div[contains(text(),'%s')]";
private static final String CLEAR_IMPORT_FILE_BTN = "//div[@class='tb-file-clear-container']//button";
private static final String OPEN_RULE_CHAIN = ENTITY + "/../..//mat-icon[contains(text(),' settings_ethernet')]";
private static final String OPEN_RULE_CHAIN_FROM_VIEW = "//span[contains(text(),'Open rule chain')]";
private static final String MAKE_ROOT_FROM_VIEW = "(//span[contains(text(),' Make rule chain root ')]/..)[1]";
private static final String ROOT_ACTIVE_CHECKBOXES = "//mat-icon[text() = 'check_box']";
private static final String ALL_NAMES = "//mat-icon[contains(text(),'check')]/../../../mat-cell[contains(@class,'name')]/span";
public String getDeleteRuleChainFromViewBtn() {
return DELETE_RULE_CHAIN_FROM_VIEW_BTN;
}
public WebElement makeRootBtn(String entityName) {
return waitUntilElementToBeClickable(String.format(MAKE_ROOT_BTN, entityName));
}
public List<WebElement> rootCheckBoxesEnable() {
return waitUntilVisibilityOfElementsLocated(ROOT_ACTIVE_CHECKBOXES);
}
public WebElement rootCheckBoxEnable(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(ROOT, entityName));
}
public WebElement rootCheckBoxDisable(String entityName) {
return waitUntilVisibilityOfElementLocated(String.format(ROOT_DISABLE, entityName));
}
public WebElement createRuleChainBtn() {
return waitUntilElementToBeClickable(CREATE_RULE_CHAIN_BTN);
}
public WebElement importRuleChainBtn() {
return waitUntilElementToBeClickable(IMPORT_RULE_CHAIN_BTN);
}
public WebElement nameField() {
return waitUntilElementToBeClickable(CREATE_RULE_CHAIN_NAME_FIELD);
}
public List<WebElement> notRootRuleChainsNames() {
return waitUntilVisibilityOfElementsLocated(RULE_CHAINS_NAMES_WITHOUT_ROOT);
}
public WebElement deleteBtnFromView() {
return waitUntilElementToBeClickable(DELETE_RULE_CHAIN_FROM_VIEW_BTN);
}
public WebElement browseFile() {
waitUntilElementToBeClickable(BROWSE_FILE + "/preceding-sibling::button");
return driver.findElement(By.xpath(BROWSE_FILE));
}
public WebElement importBrowseFileBtn() {
return waitUntilElementToBeClickable(IMPORT_BROWSE_FILE);
}
public WebElement importingFile(String fileName) {
return waitUntilVisibilityOfElementLocated(String.format(IMPORTING_FILE, fileName));
}
public WebElement clearImportFileBtn() {
return waitUntilElementToBeClickable(CLEAR_IMPORT_FILE_BTN);
}
public WebElement openRuleChainFromViewBtn() {
return waitUntilElementToBeClickable(OPEN_RULE_CHAIN_FROM_VIEW);
}
public WebElement openRuleChainBtn(String name) {
return waitUntilElementToBeClickable(String.format(OPEN_RULE_CHAIN, name));
}
public List<WebElement> entities(String name) {
return waitUntilVisibilityOfElementsLocated(String.format(ENTITY, name));
}
public WebElement makeRootFromViewBtn() {
return waitUntilElementToBeClickable(MAKE_ROOT_FROM_VIEW);
}
public List<WebElement> allNames() {
return waitUntilVisibilityOfElementsLocated(ALL_NAMES);
}
public WebElement createdTimeEntity(String name, String time) {
return waitUntilElementToBeClickable(String.format(CREATED_TIME, name, time));
}
}

124
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/RuleChainsPageHelper.java

@ -0,0 +1,124 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.testng.Assert;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
@Slf4j
public class RuleChainsPageHelper extends RuleChainsPageElements {
public RuleChainsPageHelper(WebDriver driver) {
super(driver);
}
public void openCreateRuleChainView() {
plusBtn().click();
createRuleChainBtn().click();
}
public void openImportRuleChainView() {
plusBtn().click();
importRuleChainBtn().click();
}
private int getRandomNumberFromRuleChainsCount() {
Random random = new Random();
return random.nextInt(notRootRuleChainsNames().size());
}
private String ruleChainName;
public void setRuleChainNameWithoutRoot() {
this.ruleChainName = notRootRuleChainsNames().get(getRandomNumberFromRuleChainsCount()).getText();
}
public void setRuleChainNameWithoutRoot(int number) {
this.ruleChainName = notRootRuleChainsNames().get(number).getText();
}
public void setRuleChainName(int number) {
this.ruleChainName = allNames().get(number).getText();
}
public String getRuleChainName() {
return this.ruleChainName;
}
public String deleteRuleChainFromView(String ruleChainName) {
String s = "";
if (deleteBtnFromView() != null) {
deleteBtnFromView().click();
warningPopUpYesBtn().click();
if (elementIsNotPresent(getWarningMessage())) {
return getEntity(ruleChainName);
}
} else {
for (int i = 0; i < notRootRuleChainsNames().size(); i++) {
notRootRuleChainsNames().get(i).click();
if (deleteBtnFromView() != null) {
deleteBtnFromView().click();
warningPopUpYesBtn().click();
if (elementIsNotPresent(getWarningMessage())) {
s = notRootRuleChainsNames().get(i).getText();
break;
}
}
}
}
return s;
}
public void assertCheckBoxIsNotDisplayed(String entityName) {
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//mat-checkbox)[2]")));
Assert.assertFalse(driver.findElement(By.xpath(getCheckbox(entityName))).isDisplayed());
}
public boolean deleteBtnInRootRuleChainIsNotDisplayed() {
return wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(getDeleteRuleChainFromViewBtn())));
}
public boolean ruleChainsIsNotPresent(String ruleChainName) {
return elementsIsNotPresent(getEntity(ruleChainName));
}
public void doubleClickOnRuleChain(String ruleChainName) {
doubleClick(entity(ruleChainName));
}
public void sortByNameDown() {
doubleClick(sortByNameBtn());
}
ArrayList<String> sort;
public void setSort() {
ArrayList<String> createdTime = new ArrayList<>();
createdTime().forEach(x -> createdTime.add(x.getText()));
Collections.sort(createdTime);
sort = createdTime;
}
public ArrayList<String> getSort() {
return sort;
}
}

42
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/SideBarMenuViewElements.java

@ -0,0 +1,42 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.thingsboard.server.msa.ui.base.AbstractBasePage;
public class SideBarMenuViewElements extends AbstractBasePage {
public SideBarMenuViewElements(WebDriver driver) {
super(driver);
}
private static final String RULE_CHAINS_BTN = "//mat-toolbar//a[@href='/ruleChains']";
private static final String CUSTOMER_BTN = "//mat-toolbar//a[@href='/customers']";
private static final String DASHBOARD_BTN = "//mat-toolbar//a[@href='/dashboards']";
public WebElement ruleChainsBtn() {
return waitUntilElementToBeClickable(RULE_CHAINS_BTN);
}
public WebElement customerBtn() {
return waitUntilElementToBeClickable(CUSTOMER_BTN);
}
public WebElement dashboardBtn() {
return waitUntilElementToBeClickable(DASHBOARD_BTN);
}
}

185
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/CreateCustomerTest.java

@ -0,0 +1,185 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.EMPTY_CUSTOMER_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.SAME_NAME_WARNING_CUSTOMER_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
public class CreateCustomerTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private String customerName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@AfterMethod
public void delete() {
if (customerName != null) {
testRestClient.deleteCustomer(getCustomerByName(customerName).getId());
customerName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void createCustomer() {
String customerName = ENTITY_NAME;
sideBarMenuView.customerBtn().click();
customerPage.plusBtn().click();
customerPage.titleFieldAddEntityView().sendKeys(customerName);
customerPage.addBtnC().click();
this.customerName = customerName;
customerPage.refreshBtn().click();
Assert.assertNotNull(customerPage.customer(customerName));
Assert.assertTrue(customerPage.customer(customerName).isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void createCustomerWithFullInformation() {
String customerName = ENTITY_NAME;
String text = "Text";
String email = "email@mail.com";
String number = "12015550123";
sideBarMenuView.customerBtn().click();
customerPage.plusBtn().click();
customerPage.titleFieldAddEntityView().sendKeys(customerName);
customerPage.selectCountryAddEntityView();
customerPage.descriptionAddEntityView().sendKeys(text);
customerPage.cityAddEntityView().sendKeys(text);
customerPage.stateAddEntityView().sendKeys(text);
customerPage.zipAddEntityView().sendKeys(text);
customerPage.addressAddEntityView().sendKeys(text);
customerPage.address2AddEntityView().sendKeys(text);
customerPage.phoneNumberAddEntityView().sendKeys(number);
customerPage.emailAddEntityView().sendKeys(email);
customerPage.addBtnC().click();
this.customerName = customerName;
customerPage.setCustomerEmail(customerName);
customerPage.setCustomerCountry(customerName);
customerPage.setCustomerCity(customerName);
customerPage.entity(customerName).click();
Assert.assertNotNull(customerPage.customer(customerName));
Assert.assertEquals(customerPage.entityViewTitle().getText(), customerName);
Assert.assertEquals(customerPage.titleFieldEntityView().getAttribute("value"), customerName);
Assert.assertEquals(customerPage.countrySelectMenuEntityView().getText(), customerPage.getCountry());
Assert.assertEquals(customerPage.descriptionEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.cityEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.stateEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.zipEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.addressEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.address2EntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.phoneNumberEntityView().getAttribute("value"), "+" + number);
Assert.assertEquals(customerPage.emailEntityView().getAttribute("value"), email);
Assert.assertEquals(customerPage.getCustomerEmail(), email);
Assert.assertEquals(customerPage.getCustomerCountry(), customerPage.getCountry());
Assert.assertEquals(customerPage.getCustomerCity(), text);
}
@Test(priority = 20, groups = "smoke")
@Description
public void createCustomerWithoutName() {
sideBarMenuView.customerBtn().click();
customerPage.plusBtn().click();
Assert.assertFalse(customerPage.addBtnV().isEnabled());
}
@Test(priority = 20, groups = "smoke")
@Description
public void createCustomerWithOnlySpace() {
sideBarMenuView.customerBtn().click();
customerPage.plusBtn().click();
customerPage.titleFieldAddEntityView().sendKeys(" ");
customerPage.addBtnC().click();
Assert.assertNotNull(customerPage.warningMessage());
Assert.assertTrue(customerPage.warningMessage().isDisplayed());
Assert.assertEquals(customerPage.warningMessage().getText(), EMPTY_CUSTOMER_MESSAGE);
Assert.assertNotNull(customerPage.addEntityView());
Assert.assertTrue(customerPage.addEntityView().isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void createCustomerSameName() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
String customerName = customerPage.getCustomerName();
customerPage.plusBtn().click();
customerPage.titleFieldAddEntityView().sendKeys(customerName);
customerPage.addBtnC().click();
Assert.assertNotNull(customerPage.warningMessage());
Assert.assertTrue(customerPage.warningMessage().isDisplayed());
Assert.assertEquals(customerPage.warningMessage().getText(), SAME_NAME_WARNING_CUSTOMER_MESSAGE);
Assert.assertNotNull(customerPage.addEntityView());
Assert.assertTrue(customerPage.addEntityView().isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void createCustomerWithoutRefresh() {
String customerName = ENTITY_NAME;
sideBarMenuView.customerBtn().click();
customerPage.plusBtn().click();
customerPage.titleFieldAddEntityView().sendKeys(customerName);
customerPage.addBtnC().click();
this.customerName = customerName;
Assert.assertNotNull(customerPage.customer(customerName));
Assert.assertTrue(customerPage.customer(customerName).isDisplayed());
}
@Test(priority = 40, groups = "smoke")
@Description
public void documentation() {
String urlPath = "docs/user-guide/ui/customers/";
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.customer(customerPage.getCustomerName()).click();
customerPage.goToHelpPage();
Assert.assertTrue(urlContains(urlPath));
}
}

293
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/CustomerEditMenuTest.java

@ -0,0 +1,293 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.DashboardPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.DataProviderCredential;
import static org.thingsboard.server.msa.ui.base.AbstractBasePage.getRandomNumber;
import static org.thingsboard.server.msa.ui.utils.Const.EMPTY_CUSTOMER_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.PHONE_NUMBER_ERROR_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultCustomerPrototype;
public class CustomerEditMenuTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private DashboardPageHelper dashboardPage;
private String customerName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
dashboardPage = new DashboardPageHelper(driver);
}
@AfterMethod
public void delete() {
if (customerName != null) {
testRestClient.deleteCustomer(getCustomerByName(customerName).getId());
customerName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void changeTitle() {
String customerName = "Changed" + getRandomNumber();
testRestClient.postCustomer(defaultCustomerPrototype(ENTITY_NAME));
this.customerName = customerName;
sideBarMenuView.customerBtn().click();
customerPage.entityTitles().get(0).click();
customerPage.setHeaderName();
String titleBefore = customerPage.getHeaderName();
customerPage.editPencilBtn().click();
customerPage.changeTitleEditMenu(customerName);
customerPage.doneBtnEditView().click();
customerPage.setHeaderName();
String titleAfter = customerPage.getHeaderName();
Assert.assertNotEquals(titleBefore, titleAfter);
Assert.assertEquals(titleAfter, customerName);
}
@Test(priority = 20, groups = "smoke")
@Description
public void deleteTitle() {
sideBarMenuView.customerBtn().click();
customerPage.entityTitles().get(0).click();
customerPage.editPencilBtn().click();
customerPage.titleFieldEntityView().clear();
Assert.assertFalse(customerPage.doneBtnEditViewVisible().isEnabled());
}
@Test(priority = 20, groups = "smoke")
@Description
public void saveOnlyWithSpace() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.entityTitles().get(0).click();
customerPage.editPencilBtn().click();
customerPage.changeTitleEditMenu(" ");
customerPage.doneBtnEditView().click();
customerPage.setHeaderName();
Assert.assertNotNull(customerPage.warningMessage());
Assert.assertTrue(customerPage.warningMessage().isDisplayed());
Assert.assertEquals(customerPage.warningMessage().getText(), EMPTY_CUSTOMER_MESSAGE);
Assert.assertEquals(customerPage.getCustomerName(), customerPage.getHeaderName());
}
@Test(priority = 20, groups = "smoke")
@Description
public void editDescription() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName;
String description = "Description";
sideBarMenuView.customerBtn().click();
customerPage.entityTitles().get(0).click();
customerPage.editPencilBtn().click();
customerPage.descriptionEntityView().sendKeys(description);
customerPage.doneBtnEditView().click();
String description1 = customerPage.descriptionEntityView().getAttribute("value");
customerPage.editPencilBtn().click();
customerPage.descriptionEntityView().sendKeys(description);
customerPage.doneBtnEditView().click();
String description2 = customerPage.descriptionEntityView().getAttribute("value");
customerPage.editPencilBtn().click();
customerPage.changeDescription("");
customerPage.doneBtnEditView().click();
Assert.assertEquals(description, description1);
Assert.assertEquals(description + description, description2);
Assert.assertTrue(customerPage.descriptionEntityView().getAttribute("value").isEmpty());
}
@Test(priority = 20, groups = "smoke")
@Description
public void assignedDashboardFromDashboard() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName;
sideBarMenuView.dashboardBtn().click();
dashboardPage.setDashboardTitle();
dashboardPage.assignedBtn(dashboardPage.getDashboardTitle()).click();
dashboardPage.assignedCustomer(customerName);
sideBarMenuView.customerBtn().click();
customerPage.entity(customerName).click();
customerPage.editPencilBtn().click();
customerPage.chooseDashboard();
customerPage.doneBtnEditView().click();
customerPage.setDashboardFromView();
customerPage.closeEntityViewBtn().click();
customerPage.manageCustomersUserBtn(customerName).click();
customerPage.createCustomersUser();
customerPage.userLoginBtn().click();
Assert.assertNotNull(customerPage.usersWidget());
Assert.assertTrue(customerPage.usersWidget().isDisplayed());
Assert.assertEquals(customerPage.getDashboardFromView(), dashboardPage.getDashboardTitle());
}
@Test(priority = 20, groups = "smoke")
@Description
public void assignedDashboard() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName;
sideBarMenuView.customerBtn().click();
customerPage.manageCustomersDashboardsBtn(customerName).click();
customerPage.assignedDashboard();
sideBarMenuView.customerBtn().click();
customerPage.entity(customerName).click();
customerPage.editPencilBtn().click();
customerPage.chooseDashboard();
customerPage.doneBtnEditView().click();
customerPage.setDashboardFromView();
customerPage.closeEntityViewBtn().click();
customerPage.manageCustomersUserBtn(customerName).click();
customerPage.createCustomersUser();
customerPage.userLoginBtn().click();
Assert.assertNotNull(customerPage.usersWidget());
Assert.assertTrue(customerPage.usersWidget().isDisplayed());
Assert.assertEquals(customerPage.getDashboard(), customerPage.getDashboardFromView());
}
@Test(priority = 20, groups = "smoke")
@Description
public void assignedDashboardWithoutHide() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName;
sideBarMenuView.customerBtn().click();
customerPage.manageCustomersDashboardsBtn(customerName).click();
customerPage.assignedDashboard();
sideBarMenuView.customerBtn().click();
customerPage.entity(customerName).click();
customerPage.editPencilBtn().click();
customerPage.chooseDashboard();
customerPage.hideHomeDashboardToolbarCheckbox().click();
customerPage.doneBtnEditView().click();
customerPage.setDashboardFromView();
customerPage.closeEntityViewBtn().click();
customerPage.manageCustomersUserBtn(customerName).click();
customerPage.createCustomersUser();
customerPage.userLoginBtn().click();
Assert.assertNotNull(customerPage.usersWidget());
Assert.assertTrue(customerPage.usersWidget().isDisplayed());
Assert.assertEquals(customerPage.getDashboard(), customerPage.getDashboardFromView());
Assert.assertNotNull(customerPage.stateController());
Assert.assertNotNull(customerPage.filterBtn());
Assert.assertNotNull(customerPage.timeBtn());
Assert.assertTrue(customerPage.stateController().isDisplayed());
Assert.assertTrue(customerPage.filterBtn().isDisplayed());
Assert.assertTrue(customerPage.timeBtn().isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void addPhoneNumber() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName;
String number = "2015550123";
sideBarMenuView.customerBtn().click();
customerPage.entityTitles().get(0).click();
customerPage.editPencilBtn().click();
customerPage.phoneNumberEntityView().sendKeys(number);
customerPage.doneBtnEditView().click();
Assert.assertTrue(customerPage.phoneNumberEntityView().getAttribute("value").contains(number));
}
@Test(priority = 20, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "incorrectPhoneNumber")
@Description
public void addIncorrectPhoneNumber(String number) {
sideBarMenuView.customerBtn().click();
customerPage.entityTitles().get(0).click();
customerPage.editPencilBtn().click();
customerPage.phoneNumberEntityView().sendKeys(number);
boolean doneBtnIsEnable = customerPage.doneBtnEditViewVisible().isEnabled();
customerPage.doneBtnEditViewVisible().click();
Assert.assertFalse(doneBtnIsEnable);
Assert.assertNotNull(customerPage.errorMessage());
Assert.assertTrue(customerPage.errorMessage().isDisplayed());
Assert.assertEquals(customerPage.errorMessage().getText(), PHONE_NUMBER_ERROR_MESSAGE);
}
@Test(priority = 30, groups = "smoke")
@Description
public void addAllInformation() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
this.customerName = customerName;
String text = "Text";
String email = "email@mail.com";
String number = "2015550123";
sideBarMenuView.customerBtn().click();
customerPage.entityTitles().get(0).click();
customerPage.editPencilBtn().click();
customerPage.selectCountryEntityView();
customerPage.descriptionEntityView().sendKeys(text);
customerPage.cityEntityView().sendKeys(text);
customerPage.stateEntityView().sendKeys(text);
customerPage.zipEntityView().sendKeys(text);
customerPage.addressEntityView().sendKeys(text);
customerPage.address2EntityView().sendKeys(text);
customerPage.phoneNumberEntityView().sendKeys(number);
customerPage.emailEntityView().sendKeys(email);
customerPage.doneBtnEditView().click();
Assert.assertEquals(customerPage.countrySelectMenuEntityView().getText(), customerPage.getCountry());
Assert.assertEquals(customerPage.descriptionEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.cityEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.stateEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.zipEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.addressEntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.address2EntityView().getAttribute("value"), text);
Assert.assertEquals(customerPage.phoneNumberEntityView().getAttribute("value"), "+1" + number);
Assert.assertEquals(customerPage.emailEntityView().getAttribute("value"), email);
}
}

102
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/DeleteCustomerTest.java

@ -0,0 +1,102 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultCustomerPrototype;
public class DeleteCustomerTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private RuleChainsPageHelper ruleChainsPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@Test(priority = 10, groups = "smoke")
@Description
public void removeCustomerByRightSideBtn() {
String customer = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customer));
sideBarMenuView.customerBtn().click();
String deletedCustomer = customerPage.deleteRuleChainTrash(customer);
customerPage.refreshBtn().click();
Assert.assertTrue(customerPage.entityIsNotPresent(deletedCustomer));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeSelectedCustomer() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
sideBarMenuView.customerBtn().click();
String deletedCustomer = customerPage.deleteSelected(customerName);
ruleChainsPage.refreshBtn().click();
Assert.assertTrue(ruleChainsPage.entityIsNotPresent(deletedCustomer));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeFromCustomerView() {
String customerName = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customerName));
sideBarMenuView.customerBtn().click();
customerPage.entity(customerName).click();
customerPage.customerViewDeleteBtn().click();
customerPage.warningPopUpYesBtn().click();
customerPage.refreshBtn().click();
Assert.assertTrue(customerPage.entityIsNotPresent(customerName));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeCustomerByRightSideBtnWithoutRefresh() {
String customer = ENTITY_NAME;
testRestClient.postCustomer(defaultCustomerPrototype(customer));
sideBarMenuView.customerBtn().click();
String deletedCustomer = customerPage.deleteRuleChainTrash(customer);
customerPage.refreshBtn().click();
Assert.assertTrue(customerPage.entityIsNotPresent(deletedCustomer));
}
}

92
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/DeleteSeveralCustomerTest.java

@ -0,0 +1,92 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultCustomerPrototype;
public class DeleteSeveralCustomerTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(priority = 10, groups = "smoke")
@Description
public void canDeleteSeveralCustomersByTopBtn() {
String title1 = ENTITY_NAME + "1";
String title2 = ENTITY_NAME + "2";
testRestClient.postCustomer(defaultCustomerPrototype(title1));
testRestClient.postCustomer(defaultCustomerPrototype(title2));
sideBarMenuView.customerBtn().click();
customerPage.clickOnCheckBoxes(2);
customerPage.deleteSelectedBtn().click();
customerPage.warningPopUpYesBtn().click();
customerPage.refreshBtn().click();
Assert.assertTrue(customerPage.customerIsNotPresent(title1));
Assert.assertTrue(customerPage.customerIsNotPresent(title2));
}
@Test(priority = 10, groups = "smoke")
@Description
public void selectAllCustomers() {
sideBarMenuView.customerBtn().click();
customerPage.selectAllCheckBox().click();
customerPage.deleteSelectedBtn().click();
Assert.assertNotNull(customerPage.warningPopUpTitle());
Assert.assertTrue(customerPage.warningPopUpTitle().isDisplayed());
Assert.assertTrue(customerPage.warningPopUpTitle().getText().contains(String.valueOf(customerPage.markCheckbox().size())));
}
@Test(priority = 30, groups = "smoke")
@Description
public void deleteSeveralCustomersByTopBtnWithoutRefresh() {
String title1 = ENTITY_NAME + "1";
String title2 = ENTITY_NAME + "2";
testRestClient.postCustomer(defaultCustomerPrototype(title1));
testRestClient.postCustomer(defaultCustomerPrototype(title2));
sideBarMenuView.customerBtn().click();
customerPage.clickOnCheckBoxes(2);
customerPage.deleteSelectedBtn().click();
customerPage.warningPopUpYesBtn().click();
Assert.assertTrue(customerPage.customerIsNotPresent(title1));
Assert.assertTrue(customerPage.customerIsNotPresent(title2));
}
}

67
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersAssetsTest.java

@ -0,0 +1,67 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
public class ManageCustomersAssetsTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private final String manage = "Assets";
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(groups = "smoke")
@Description
public void openWindowByRightCornerBtn() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.manageCustomersAssetsBtn(customerPage.getCustomerName()).click();
Assert.assertTrue(urlContains(manage.toLowerCase()));
Assert.assertNotNull(customerPage.customerAssetsIconHeader());
Assert.assertTrue(customerPage.customerAssetsIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(manage));
}
@Test(groups = "smoke")
@Description
public void openWindowByView() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.entity(customerPage.getCustomerName()).click();
customerPage.manageCustomersAssetsBtnView().click();
Assert.assertTrue(urlContains(manage.toLowerCase()));
Assert.assertNotNull(customerPage.customerAssetsIconHeader());
Assert.assertTrue(customerPage.customerAssetsIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(manage));
}
}

66
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersDashboardsTest.java

@ -0,0 +1,66 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
public class ManageCustomersDashboardsTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private final String manage = "Dashboards";
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(groups = "smoke")
@Description
public void openWindowByRightCornerBtn() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.manageCustomersDashboardsBtn(customerPage.getCustomerName()).click();
Assert.assertTrue(urlContains(manage.toLowerCase()));
Assert.assertNotNull(customerPage.customerDashboardIconHeader());
Assert.assertTrue(customerPage.customerDashboardIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(manage));
}
@Test(groups = "smoke")
@Description
public void openWindowByView() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.entity(customerPage.getCustomerName()).click();
customerPage.manageCustomersDashboardsBtnView().click();
Assert.assertTrue(urlContains(manage.toLowerCase()));
Assert.assertNotNull(customerPage.customerDashboardIconHeader());
Assert.assertTrue(customerPage.customerDashboardIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(manage));
}
}

66
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersDevicesTest.java

@ -0,0 +1,66 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
public class ManageCustomersDevicesTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private final String manage = "Devices";
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(groups = "smoke")
@Description
public void openWindowByRightCornerBtn() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.manageCustomersDevicesBtn(customerPage.getCustomerName()).click();
Assert.assertTrue(urlContains(manage.toLowerCase()));
Assert.assertNotNull(customerPage.customerDevicesIconHeader());
Assert.assertTrue(customerPage.customerDevicesIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(manage));
}
@Test(groups = "smoke")
@Description
public void openWindowByView() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.entity(customerPage.getCustomerName()).click();
customerPage.manageCustomersDeviceBtnView().click();
Assert.assertTrue(urlContains(manage.toLowerCase()));
Assert.assertNotNull(customerPage.customerDevicesIconHeader());
Assert.assertTrue(customerPage.customerDevicesIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(manage));
}
}

67
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersEdgesTest.java

@ -0,0 +1,67 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
public class ManageCustomersEdgesTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private final String iconText = "Edge instances";
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(groups = "smoke")
@Description
public void openWindowByRightCornerBtn() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.manageCustomersEdgeBtn(customerPage.getCustomerName()).click();
Assert.assertTrue(urlContains("edgeInstances"));
Assert.assertNotNull(customerPage.customerEdgeIconHeader());
Assert.assertTrue(customerPage.customerEdgeIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(iconText));
}
@Test(groups = "smoke")
@Description
public void openWindowByView() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.entity(customerPage.getCustomerName()).click();
customerPage.manageCustomersEdgeBtnView().click();
Assert.assertTrue(urlContains("edgeInstances"));
Assert.assertNotNull(customerPage.customerEdgeIconHeader());
Assert.assertTrue(customerPage.customerEdgeIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(iconText));
}
}

67
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/ManageCustomersUsersTest.java

@ -0,0 +1,67 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
public class ManageCustomersUsersTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private final String iconText = "Customer Users";
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(groups = "smoke")
@Description
public void openWindowByRightCornerBtn() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.manageCustomersUserBtn(customerPage.getCustomerName()).click();
Assert.assertTrue(urlContains("user"));
Assert.assertNotNull(customerPage.customerUserIconHeader());
Assert.assertTrue(customerPage.customerUserIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(iconText));
}
@Test(groups = "smoke")
@Description
public void openWindowByView() {
sideBarMenuView.customerBtn().click();
customerPage.setCustomerName();
customerPage.entity(customerPage.getCustomerName()).click();
customerPage.manageCustomersUserBtnView().click();
Assert.assertTrue(urlContains("user"));
Assert.assertNotNull(customerPage.customerUserIconHeader());
Assert.assertTrue(customerPage.customerUserIconHeader().isDisplayed());
Assert.assertTrue(customerPage.customerManageWindowIconHead().getText().contains(iconText));
}
}

69
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/SearchCustomerTest.java

@ -0,0 +1,69 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.DataProviderCredential;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultCustomerPrototype;
public class SearchCustomerTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "customerNameForSearchByFirstAndSecondWord")
@Description
public void searchFirstWord(String namePath) {
sideBarMenuView.customerBtn().click();
customerPage.searchEntity(namePath);
customerPage.allEntity().forEach(x -> Assert.assertTrue(x.getText().contains(namePath)));
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForSearchBySymbolAndNumber")
@Description
public void searchNumber(String name, String namePath) {
testRestClient.postCustomer(defaultCustomerPrototype(name));
sideBarMenuView.customerBtn().click();
customerPage.searchEntity(namePath);
customerPage.setCustomerName();
boolean customerNameContainsPath = customerPage.getCustomerName().contains(namePath);
testRestClient.deleteCustomer(getCustomerByName(name).getId());
Assert.assertTrue(customerNameContainsPath);
}
}

131
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/customerSmoke/SortByNameTest.java

@ -0,0 +1,131 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.customerSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.CustomerPageHelper;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.DataProviderCredential;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultCustomerPrototype;
public class SortByNameTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private CustomerPageHelper customerPage;
private String customerName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
customerPage = new CustomerPageHelper(driver);
}
@AfterMethod
public void delete() {
if (customerName != null) {
testRestClient.deleteCustomer(getCustomerByName(customerName).getId());
customerName = null;
}
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForSort")
@Description
public void specialCharacterUp(String title) {
testRestClient.postCustomer(defaultCustomerPrototype(title));
this.customerName = title;
sideBarMenuView.customerBtn().click();
customerPage.sortByTitleBtn().click();
customerPage.setCustomerName();
Assert.assertEquals(customerPage.getCustomerName(), title);
}
@Test(priority = 20, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForAllSort")
@Description
public void allSortUp(String customer, String customerSymbol, String customerNumber) {
testRestClient.postCustomer(defaultCustomerPrototype(customerSymbol));
testRestClient.postCustomer(defaultCustomerPrototype(customer));
testRestClient.postCustomer(defaultCustomerPrototype(customerNumber));
sideBarMenuView.customerBtn().click();
customerPage.sortByTitleBtn().click();
customerPage.setCustomerName(0);
String firstCustomer = customerPage.getCustomerName();
customerPage.setCustomerName(1);
String secondCustomer = customerPage.getCustomerName();
customerPage.setCustomerName(2);
String thirdCustomer = customerPage.getCustomerName();
testRestClient.deleteCustomer(getCustomerByName(customer).getId());
testRestClient.deleteCustomer(getCustomerByName(customerNumber).getId());
testRestClient.deleteCustomer(getCustomerByName(customerSymbol).getId());
Assert.assertEquals(firstCustomer, customerSymbol);
Assert.assertEquals(secondCustomer, customerNumber);
Assert.assertEquals(thirdCustomer, customer);
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForSort")
@Description
public void specialCharacterDown(String title) {
testRestClient.postCustomer(defaultCustomerPrototype(title));
customerName = title;
sideBarMenuView.customerBtn().click();
customerPage.sortByNameDown();
customerPage.setCustomerName(customerPage.allEntity().size() - 1);
Assert.assertEquals(customerPage.getCustomerName(), title);
}
@Test(priority = 20, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForAllSort")
@Description
public void allSortDown(String customer, String customerSymbol, String customerNumber) {
testRestClient.postCustomer(defaultCustomerPrototype(customerSymbol));
testRestClient.postCustomer(defaultCustomerPrototype(customer));
testRestClient.postCustomer(defaultCustomerPrototype(customerNumber));
sideBarMenuView.customerBtn().click();
int lastIndex = customerPage.allEntity().size() - 1;
customerPage.sortByNameDown();
customerPage.setCustomerName(lastIndex);
String firstCustomer = customerPage.getCustomerName();
customerPage.setCustomerName(lastIndex - 1);
String secondCustomer = customerPage.getCustomerName();
customerPage.setCustomerName(lastIndex - 2);
String thirdCustomer = customerPage.getCustomerName();
testRestClient.deleteCustomer(getCustomerByName(customer).getId());
testRestClient.deleteCustomer(getCustomerByName(customerNumber).getId());
testRestClient.deleteCustomer(getCustomerByName(customerSymbol).getId());
Assert.assertEquals(firstCustomer, customerSymbol);
Assert.assertEquals(secondCustomer, customerNumber);
Assert.assertEquals(thirdCustomer, customer);
}
}

142
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/CreateRuleChainImportTest.java

@ -0,0 +1,142 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.OpenRuleChainPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import java.util.ArrayList;
import static org.thingsboard.server.msa.ui.utils.Const.EMPTY_IMPORT_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.IMPORT_RULE_CHAIN_FILE_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.IMPORT_RULE_CHAIN_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.IMPORT_TXT_FILE_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class CreateRuleChainImportTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
private OpenRuleChainPageHelper openRuleChainPage;
private final String absolutePathToFileImportRuleChain = getClass().getClassLoader().getResource(IMPORT_RULE_CHAIN_FILE_NAME).getPath();
private final String absolutePathToFileImportTxt = getClass().getClassLoader().getResource(IMPORT_TXT_FILE_NAME).getPath();
private String ruleChainName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
openRuleChainPage = new OpenRuleChainPageHelper(driver);
}
@AfterMethod
public void delete() {
if (ruleChainName != null) {
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
ruleChainName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void importRuleChain() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openImportRuleChainView();
ruleChainsPage.browseFile().sendKeys(absolutePathToFileImportRuleChain);
Assert.assertNotNull(ruleChainsPage.importingFile(IMPORT_RULE_CHAIN_FILE_NAME));
Assert.assertTrue(ruleChainsPage.importingFile(IMPORT_RULE_CHAIN_FILE_NAME).isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void importRuleChainAndDeleteFile() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openImportRuleChainView();
ruleChainsPage.browseFile().sendKeys(absolutePathToFileImportRuleChain);
ruleChainsPage.clearImportFileBtn().click();
Assert.assertNotNull(ruleChainsPage.importingFile(EMPTY_IMPORT_MESSAGE));
Assert.assertTrue(ruleChainsPage.importingFile(EMPTY_IMPORT_MESSAGE).isDisplayed());
Assert.assertTrue(ruleChainsPage.entityIsNotPresent(IMPORT_TXT_FILE_NAME));
}
@Test(priority = 20, groups = "smoke")
@Description
public void importTxtFile() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openImportRuleChainView();
ruleChainsPage.browseFile().sendKeys(absolutePathToFileImportTxt);
Assert.assertNotNull(ruleChainsPage.importingFile(EMPTY_IMPORT_MESSAGE));
Assert.assertTrue(ruleChainsPage.importingFile(EMPTY_IMPORT_MESSAGE).isDisplayed());
}
@Test(priority = 30, groups = "smoke")
@Description
public void importRuleChainAndSave() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openImportRuleChainView();
ruleChainsPage.browseFile().sendKeys(absolutePathToFileImportRuleChain);
ruleChainsPage.importBrowseFileBtn().click();
openRuleChainPage.doneBtn().click();
openRuleChainPage.waitUntilDoneBtnDisable();
ruleChainName = IMPORT_RULE_CHAIN_NAME;
sideBarMenuView.ruleChainsBtn().click();
Assert.assertNotNull(ruleChainsPage.entity(IMPORT_RULE_CHAIN_NAME));
Assert.assertTrue(ruleChainsPage.entity(IMPORT_RULE_CHAIN_NAME).isDisplayed());
}
@Test(priority = 40, groups = "smoke")
@Description
public void importRuleChainAndSaveWithSameName() {
String ruleChainName = IMPORT_RULE_CHAIN_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openImportRuleChainView();
ruleChainsPage.browseFile().sendKeys(absolutePathToFileImportRuleChain);
ruleChainsPage.importBrowseFileBtn().click();
openRuleChainPage.doneBtn().click();
openRuleChainPage.waitUntilDoneBtnDisable();
sideBarMenuView.ruleChainsBtn().click();
boolean entityNotNull = ruleChainsPage.entity(ruleChainName) != null;
boolean entitiesSizeMoreOne = ruleChainsPage.entities(ruleChainName).size() > 1;
ArrayList<Boolean> entityIsDisplayed = new ArrayList<>();
ruleChainsPage.entities(ruleChainName).forEach(x -> entityIsDisplayed.add(x.isDisplayed()));
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
Assert.assertTrue(entityNotNull);
Assert.assertTrue(entitiesSizeMoreOne);
entityIsDisplayed.forEach(Assert::assertTrue);
}
}

171
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/CreateRuleChainTest.java

@ -0,0 +1,171 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.EntityPrototypes;
import java.util.ArrayList;
import static org.thingsboard.server.msa.ui.utils.Const.EMPTY_RULE_CHAIN_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
public class CreateRuleChainTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
private String ruleChainName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@AfterMethod
public void delete() {
if (ruleChainName != null) {
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
ruleChainName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void createRuleChain() {
String ruleChainName = ENTITY_NAME;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openCreateRuleChainView();
ruleChainsPage.nameField().click();
ruleChainsPage.nameField().sendKeys(ruleChainName);
ruleChainsPage.addBtnC().click();
ruleChainsPage.refreshBtn().click();
this.ruleChainName = ruleChainName;
Assert.assertNotNull(ruleChainsPage.entity(ruleChainName));
Assert.assertTrue(ruleChainsPage.entity(ruleChainName).isDisplayed());
}
@Test(priority = 10, groups = "smoke")
@Description
public void createRuleChainWithDescription() {
String ruleChainName = ENTITY_NAME;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openCreateRuleChainView();
ruleChainsPage.nameField().sendKeys(ruleChainName);
ruleChainsPage.descriptionAddEntityView().sendKeys(ENTITY_NAME);
ruleChainsPage.addBtnC().click();
ruleChainsPage.refreshBtn().click();
this.ruleChainName = ruleChainName;
ruleChainsPage.detailsBtn(ENTITY_NAME).click();
ruleChainsPage.setHeaderName();
Assert.assertEquals(ruleChainsPage.getHeaderName(), ruleChainName);
Assert.assertEquals(ruleChainsPage.descriptionEntityView().getAttribute("value"), ruleChainName);
}
@Test(priority = 20, groups = "smoke")
@Description
public void createRuleChainWithoutName() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openCreateRuleChainView();
Assert.assertFalse(ruleChainsPage.addBtnV().isEnabled());
}
@Test(priority = 20, groups = "smoke")
@Description
public void createRuleChainWithOnlySpace() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openCreateRuleChainView();
ruleChainsPage.nameField().sendKeys(" ");
ruleChainsPage.addBtnC().click();
Assert.assertNotNull(ruleChainsPage.warningMessage());
Assert.assertTrue(ruleChainsPage.warningMessage().isDisplayed());
Assert.assertEquals(ruleChainsPage.warningMessage().getText(), EMPTY_RULE_CHAIN_MESSAGE);
Assert.assertNotNull(ruleChainsPage.addEntityView());
Assert.assertTrue(ruleChainsPage.addEntityView().isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void createRuleChainWithSameName() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(EntityPrototypes.defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openCreateRuleChainView();
ruleChainsPage.nameField().sendKeys(ruleChainName);
ruleChainsPage.addBtnC().click();
ruleChainsPage.refreshBtn().click();
boolean entityNotNull = ruleChainsPage.entity(ruleChainName) != null;
boolean entitiesSizeMoreOne = ruleChainsPage.entities(ruleChainName).size() > 1;
ArrayList<Boolean> entityIsDisplayed = new ArrayList<>();
ruleChainsPage.entities(ruleChainName).forEach(x -> entityIsDisplayed.add(x.isDisplayed()));
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
Assert.assertTrue(entityNotNull);
Assert.assertTrue(entitiesSizeMoreOne);
entityIsDisplayed.forEach(Assert::assertTrue);
}
@Test(priority = 30, groups = "smoke")
@Description
public void createRuleChainWithoutRefresh() {
String ruleChainName = ENTITY_NAME;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.openCreateRuleChainView();
ruleChainsPage.nameField().sendKeys(ruleChainName);
ruleChainsPage.addBtnC().click();
this.ruleChainName = ruleChainName;
Assert.assertNotNull(ruleChainsPage.entity(ruleChainName));
Assert.assertTrue(ruleChainsPage.entity(ruleChainName).isDisplayed());
}
@Test(priority = 40, groups = "smoke")
@Description
public void documentation() {
String urlPath = "docs/user-guide/ui/rule-chains/";
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.setRuleChainNameWithoutRoot();
ruleChainsPage.detailsBtn(ruleChainsPage.getRuleChainName()).click();
ruleChainsPage.goToHelpPage();
Assert.assertTrue(urlContains(urlPath));
}
}

171
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/DeleteRuleChainTest.java

@ -0,0 +1,171 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.DELETE_RULE_CHAIN_WITH_PROFILE_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.ROOT_RULE_CHAIN_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class DeleteRuleChainTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@Test(priority = 10, groups = "smoke")
@Description
public void removeRuleChainByRightSideBtn() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
String deletedRuleChain = ruleChainsPage.deleteRuleChainTrash(ruleChainName);
ruleChainsPage.refreshBtn().click();
Assert.assertTrue(ruleChainsPage.entityIsNotPresent(deletedRuleChain));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeSelectedRuleChain() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
String deletedRuleChain = ruleChainsPage.deleteSelected(ruleChainName);
ruleChainsPage.refreshBtn().click();
Assert.assertTrue(ruleChainsPage.entityIsNotPresent(deletedRuleChain));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeFromRuleChainView() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ENTITY_NAME).click();
String deletedRuleChain = ruleChainsPage.deleteRuleChainFromView(ruleChainName);
ruleChainsPage.refreshBtn().click();
Assert.assertTrue(ruleChainsPage.entityIsNotPresent(deletedRuleChain));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeRootRuleChain() {
sideBarMenuView.ruleChainsBtn().click();
Assert.assertFalse(ruleChainsPage.deleteBtn(ROOT_RULE_CHAIN_NAME).isEnabled());
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeSelectedRootRuleChain() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.assertCheckBoxIsNotDisplayed(ROOT_RULE_CHAIN_NAME);
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeFromRootRuleChainView() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ROOT_RULE_CHAIN_NAME).click();
ruleChainsPage.deleteBtnFromView();
Assert.assertTrue(ruleChainsPage.deleteBtnInRootRuleChainIsNotDisplayed());
}
@Test(priority = 10, groups = "smoke")
@Description
public void removeProfileRuleChainByRightSideBtn() {
String deletedRuleChain = "Thermostat";
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.deleteBtn(deletedRuleChain).click();
ruleChainsPage.warningPopUpYesBtn().click();
ruleChainsPage.refreshBtn().click();
Assert.assertNotNull(ruleChainsPage.entity(deletedRuleChain));
Assert.assertTrue(ruleChainsPage.entity(deletedRuleChain).isDisplayed());
Assert.assertNotNull(ruleChainsPage.warningMessage());
Assert.assertTrue(ruleChainsPage.warningMessage().isDisplayed());
Assert.assertEquals(ruleChainsPage.warningMessage().getText(), DELETE_RULE_CHAIN_WITH_PROFILE_MESSAGE);
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeSelectedProfileRuleChain() {
sideBarMenuView.ruleChainsBtn().click();
String deletedRuleChain = ruleChainsPage.deleteSelected("Thermostat");
ruleChainsPage.refreshBtn().click();
Assert.assertNotNull(ruleChainsPage.entity(deletedRuleChain));
Assert.assertTrue(ruleChainsPage.entity(deletedRuleChain).isDisplayed());
Assert.assertNotNull(ruleChainsPage.warningMessage());
Assert.assertTrue(ruleChainsPage.warningMessage().isDisplayed());
Assert.assertEquals(ruleChainsPage.warningMessage().getText(), DELETE_RULE_CHAIN_WITH_PROFILE_MESSAGE);
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeFromProfileRuleChainView() {
String deletedRuleChain = "Thermostat";
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(deletedRuleChain).click();
ruleChainsPage.deleteBtnFromView().click();
ruleChainsPage.warningPopUpYesBtn().click();
Assert.assertNotNull(ruleChainsPage.entity(deletedRuleChain));
Assert.assertNotNull(ruleChainsPage.warningMessage());
Assert.assertTrue(ruleChainsPage.warningMessage().isDisplayed());
Assert.assertEquals(ruleChainsPage.warningMessage().getText(), DELETE_RULE_CHAIN_WITH_PROFILE_MESSAGE);
}
@Test(priority = 30, groups = "smoke")
@Description
public void removeRuleChainByRightSideBtnWithoutRefresh() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
String deletedRuleChain = ruleChainsPage.deleteRuleChainTrash(ruleChainName);
Assert.assertTrue(ruleChainsPage.entityIsNotPresent(deletedRuleChain));
}
}

111
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/DeleteSeveralRuleChainsTest.java

@ -0,0 +1,111 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.ROOT_RULE_CHAIN_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class DeleteSeveralRuleChainsTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@Test(priority = 10, groups = "smoke")
@Description
public void canDeleteSeveralRuleChainsByTopBtn() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName + 1));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.clickOnCheckBoxes(2);
ruleChainsPage.deleteSelectedBtn().click();
ruleChainsPage.warningPopUpYesBtn().click();
ruleChainsPage.refreshBtn().click();
Assert.assertTrue(ruleChainsPage.ruleChainsIsNotPresent(ruleChainName));
}
@Test(priority = 10, groups = "smoke")
@Description
public void selectAllRuleChain() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName + 1));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.selectAllCheckBox().click();
ruleChainsPage.deleteSelectedBtn().click();
ruleChainsPage.warningPopUpYesBtn().click();
ruleChainsPage.refreshBtn().click();
Assert.assertTrue(ruleChainsPage.ruleChainsIsNotPresent(ruleChainName));
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeRootRuleChain() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.selectAllCheckBox().click();
Assert.assertFalse(ruleChainsPage.deleteBtn(ROOT_RULE_CHAIN_NAME).isEnabled());
}
@Test(priority = 20, groups = "smoke")
@Description
public void removeSelectedRootRuleChain() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.selectAllCheckBox().click();
ruleChainsPage.assertCheckBoxIsNotDisplayed(ROOT_RULE_CHAIN_NAME);
}
@Test(priority = 30, groups = "smoke")
@Description
public void deleteSeveralRuleChainsByTopBtnWithoutRefresh() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName + 1));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.clickOnCheckBoxes(2);
ruleChainsPage.deleteSelectedBtn().click();
ruleChainsPage.warningPopUpYesBtn().click();
Assert.assertTrue(ruleChainsPage.ruleChainsIsNotPresent(ruleChainName));
}
}

89
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/MakeRuleChainRootTest.java

@ -0,0 +1,89 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
public class MakeRuleChainRootTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@AfterMethod
public void makeRoot() {
testRestClient.setRootRuleChain(getRuleChainByName("Root Rule Chain").getId());
}
@Test(priority = 10, groups = "smoke")
@Description
public void makeRuleChainRootByRightCornerBtn() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.setRuleChainNameWithoutRoot(0);
String ruleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.makeRootBtn(ruleChain).click();
ruleChainsPage.warningPopUpYesBtn().click();
Assert.assertTrue(ruleChainsPage.rootCheckBoxEnable(ruleChain).isDisplayed());
}
@Test(priority = 20, groups = "smoke")
@Description
public void makeRuleChainRootFromView() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.setRuleChainNameWithoutRoot(0);
String ruleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.detailsBtn(ruleChain).click();
ruleChainsPage.makeRootFromViewBtn().click();
ruleChainsPage.warningPopUpYesBtn().click();
ruleChainsPage.closeEntityViewBtn().click();
Assert.assertTrue(ruleChainsPage.rootCheckBoxEnable(ruleChain).isDisplayed());
}
@Test(priority = 30, groups = "smoke")
@Description
public void multiplyRoot() {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.setRuleChainNameWithoutRoot(0);
String ruleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.detailsBtn(ruleChain).click();
ruleChainsPage.makeRootFromViewBtn().click();
ruleChainsPage.warningPopUpYesBtn().click();
ruleChainsPage.closeEntityViewBtn().click();
Assert.assertEquals(ruleChainsPage.rootCheckBoxesEnable().size(), 1);
}
}

93
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/OpenRuleChainTest.java

@ -0,0 +1,93 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.OpenRuleChainPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.EntityPrototypes;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
public class OpenRuleChainTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
private OpenRuleChainPageHelper openRuleChainPage;
private String ruleChainName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
openRuleChainPage = new OpenRuleChainPageHelper(driver);
}
@AfterMethod
public void delete(){
if (ruleChainName != null) {
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
ruleChainName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void openRuleChainByRightCornerBtn() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(EntityPrototypes.defaultRuleChainPrototype(ENTITY_NAME));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.entity(ruleChainName).click();
openRuleChainPage.setHeadName();
Assert.assertTrue(urlContains(String.valueOf(getRuleChainByName(ruleChainName).getId())));
Assert.assertTrue(openRuleChainPage.headRuleChainName().isDisplayed());
Assert.assertTrue(openRuleChainPage.inputNode().isDisplayed());
Assert.assertEquals(ruleChainName, openRuleChainPage.getHeadName());
}
@Test(priority = 10, groups = "smoke")
@Description
public void openRuleChainByViewBtn() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(EntityPrototypes.defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ruleChainName).click();
ruleChainsPage.openRuleChainFromViewBtn().click();
openRuleChainPage.setHeadName();
Assert.assertTrue(urlContains(String.valueOf(getRuleChainByName(ruleChainName).getId())));
Assert.assertTrue(openRuleChainPage.headRuleChainName().isDisplayed());
Assert.assertTrue(openRuleChainPage.inputNode().isDisplayed());
Assert.assertEquals(ruleChainName, openRuleChainPage.getHeadName());
}
}

160
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/RuleChainEditMenuTest.java

@ -0,0 +1,160 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.EMPTY_RULE_CHAIN_MESSAGE;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class RuleChainEditMenuTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
private String ruleChainName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@AfterMethod
public void delete() {
if (ruleChainName != null) {
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
ruleChainName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void changeName() {
String newRuleChainName = "Changed";
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ruleChainName).click();
ruleChainsPage.setHeaderName();
String nameBefore = ruleChainsPage.getHeaderName();
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.changeNameEditMenu(newRuleChainName);
ruleChainsPage.doneBtnEditView().click();
this.ruleChainName = newRuleChainName;
ruleChainsPage.setHeaderName();
String nameAfter = ruleChainsPage.getHeaderName();
Assert.assertNotEquals(nameBefore, nameAfter);
Assert.assertEquals(newRuleChainName, nameAfter);
}
@Test(priority = 20, groups = "smoke")
@Description
public void deleteName() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ruleChainName).click();
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.changeNameEditMenu("");
Assert.assertFalse(ruleChainsPage.doneBtnEditViewVisible().isEnabled());
}
@Test(priority = 20, groups = "smoke")
@Description
public void saveOnlyWithSpace() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ruleChainName).click();
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.changeNameEditMenu(" ");
ruleChainsPage.doneBtnEditView().click();
Assert.assertNotNull(ruleChainsPage.warningMessage());
Assert.assertTrue(ruleChainsPage.warningMessage().isDisplayed());
Assert.assertEquals(ruleChainsPage.warningMessage().getText(), EMPTY_RULE_CHAIN_MESSAGE);
}
@Test(priority = 20, groups = "smoke")
@Description
public void editDescription() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
String description = "Description";
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ruleChainName).click();
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.descriptionEntityView().sendKeys(description);
ruleChainsPage.doneBtnEditView().click();
String description1 = ruleChainsPage.descriptionEntityView().getAttribute("value");
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.descriptionEntityView().sendKeys(description);
ruleChainsPage.doneBtnEditView().click();
String description2 = ruleChainsPage.descriptionEntityView().getAttribute("value");
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.changeDescription("");
ruleChainsPage.doneBtnEditView().click();
Assert.assertTrue(ruleChainsPage.descriptionEntityView().getAttribute("value").isEmpty());
Assert.assertEquals(description, description1);
Assert.assertEquals(description + description, description2);
}
@Test(priority = 20, groups = "smoke")
@Description
public void debugMode() {
String ruleChainName = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.detailsBtn(ruleChainName).click();
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.debugCheckboxEdit().click();
ruleChainsPage.doneBtnEditView().click();
boolean debugMode = Boolean.parseBoolean(ruleChainsPage.debugCheckboxView().getAttribute("aria-checked"));
ruleChainsPage.editPencilBtn().click();
ruleChainsPage.debugCheckboxEdit().click();
ruleChainsPage.doneBtnEditView().click();
Assert.assertFalse(Boolean.parseBoolean(ruleChainsPage.debugCheckboxView().getAttribute("aria-checked")));
Assert.assertTrue(debugMode);
}
}

70
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/SearchRuleChainTest.java

@ -0,0 +1,70 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.DataProviderCredential;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class SearchRuleChainTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "ruleChainNameForSearchByFirstAndSecondWord")
@Description
public void searchFirstWord(String namePath) {
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.searchEntity(namePath);
ruleChainsPage.setRuleChainName(0);
Assert.assertTrue(ruleChainsPage.getRuleChainName().contains(namePath));
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForSearchBySymbolAndNumber")
@Description
public void searchNumber(String name, String namePath) {
testRestClient.postRuleChain(defaultRuleChainPrototype(name));
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.searchEntity(namePath);
ruleChainsPage.setRuleChainName(0);
boolean ruleChainContainsNamePath = ruleChainsPage.getRuleChainName().contains(namePath);
testRestClient.deleteRuleChain(getRuleChainByName(name).getId());
Assert.assertTrue(ruleChainContainsNamePath);
}
}

132
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/SortByNameTest.java

@ -0,0 +1,132 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import org.thingsboard.server.msa.ui.utils.DataProviderCredential;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class SortByNameTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
private String ruleChainName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@AfterMethod
public void delete() {
if (ruleChainName != null) {
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
ruleChainName = null;
}
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForSort")
@Description
public void specialCharacterUp(String ruleChainName) {
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.sortByNameBtn().click();
ruleChainsPage.setRuleChainName(0);
Assert.assertEquals(ruleChainsPage.getRuleChainName(), ruleChainName);
}
@Test(priority = 20, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForAllSort")
@Description
public void allSortUp(String ruleChain, String ruleChainSymbol, String ruleChainNumber) {
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainSymbol));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChain));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainNumber));
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.sortByNameBtn().click();
ruleChainsPage.setRuleChainName(0);
String firstRuleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.setRuleChainName(1);
String secondRuleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.setRuleChainName(2);
String thirdRuleChain = ruleChainsPage.getRuleChainName();
testRestClient.deleteRuleChain(getRuleChainByName(ruleChain).getId());
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainNumber).getId());
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainSymbol).getId());
Assert.assertEquals(firstRuleChain, ruleChainSymbol);
Assert.assertEquals(secondRuleChain, ruleChainNumber);
Assert.assertEquals(thirdRuleChain, ruleChain);
}
@Test(priority = 10, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForSort")
@Description
public void specialCharacterDown(String ruleChainName) {
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainName));
this.ruleChainName = ruleChainName;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.sortByNameDown();
ruleChainsPage.setRuleChainName(ruleChainsPage.allNames().size() - 1);
Assert.assertEquals(ruleChainsPage.getRuleChainName(), ruleChainName);
}
@Test(priority = 20, groups = "smoke", dataProviderClass = DataProviderCredential.class, dataProvider = "nameForAllSort")
@Description
public void allSortDown(String ruleChain, String ruleChainSymbol, String ruleChainNumber) {
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainSymbol));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChain));
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChainNumber));
sideBarMenuView.ruleChainsBtn().click();
int lastIndex = ruleChainsPage.allNames().size() - 1;
ruleChainsPage.sortByNameDown();
ruleChainsPage.setRuleChainName(lastIndex);
String firstRuleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.setRuleChainName(lastIndex - 1);
String secondRuleChain = ruleChainsPage.getRuleChainName();
ruleChainsPage.setRuleChainName(lastIndex - 2);
String thirdRuleChain = ruleChainsPage.getRuleChainName();
testRestClient.deleteRuleChain(getRuleChainByName(ruleChain).getId());
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainNumber).getId());
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainSymbol).getId());
Assert.assertEquals(firstRuleChain, ruleChainSymbol);
Assert.assertEquals(secondRuleChain, ruleChainNumber);
Assert.assertEquals(thirdRuleChain, ruleChain);
}
}

88
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/ruleChainsSmoke/SortByTimeTest.java

@ -0,0 +1,88 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.tests.ruleChainsSmoke;
import io.qameta.allure.Description;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.msa.ui.base.AbstractDriverBaseTest;
import org.thingsboard.server.msa.ui.pages.LoginPageHelper;
import org.thingsboard.server.msa.ui.pages.RuleChainsPageHelper;
import org.thingsboard.server.msa.ui.pages.SideBarMenuViewElements;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_EMAIL;
import static org.thingsboard.server.msa.ui.utils.Const.TENANT_PASSWORD;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultRuleChainPrototype;
public class SortByTimeTest extends AbstractDriverBaseTest {
private SideBarMenuViewElements sideBarMenuView;
private RuleChainsPageHelper ruleChainsPage;
private String ruleChainName;
@BeforeMethod
public void login() {
openLocalhost();
new LoginPageHelper(driver).authorizationTenant();
testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD);
sideBarMenuView = new SideBarMenuViewElements(driver);
ruleChainsPage = new RuleChainsPageHelper(driver);
}
@AfterMethod
public void delete() {
if (ruleChainName != null) {
testRestClient.deleteRuleChain(getRuleChainByName(ruleChainName).getId());
ruleChainName = null;
}
}
@Test(priority = 10, groups = "smoke")
@Description
public void sortByTimeDown() {
String ruleChain = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChain));
ruleChainName = ruleChain;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.setSort();
String firstListElement = ruleChainsPage.getSort().get(ruleChainsPage.getSort().size() - 1);
String lastCreated = ruleChainsPage.createdTime().get(0).getText();
Assert.assertEquals(firstListElement, lastCreated);
Assert.assertNotNull(ruleChainsPage.createdTimeEntity(ruleChain, lastCreated));
}
@Test(priority = 10, groups = "smoke")
@Description
public void sortByTimeUp() {
String ruleChain = ENTITY_NAME;
testRestClient.postRuleChain(defaultRuleChainPrototype(ruleChain));
ruleChainName = ruleChain;
sideBarMenuView.ruleChainsBtn().click();
ruleChainsPage.sortByTimeBtn().click();
ruleChainsPage.setSort();
String firstListElement = ruleChainsPage.getSort().get(ruleChainsPage.getSort().size() - 1);
String lastCreated = ruleChainsPage.createdTime().get(ruleChainsPage.createdTime().size() - 1).getText();
Assert.assertEquals(firstListElement, lastCreated);
Assert.assertNotNull(ruleChainsPage.createdTimeEntity(ruleChain, lastCreated));
}
}

37
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/Const.java

@ -0,0 +1,37 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.utils;
import static org.thingsboard.server.msa.TestProperties.getBaseUrl;
import static org.thingsboard.server.msa.ui.base.AbstractBasePage.getRandomNumber;
public class Const {
public static final String URL = getBaseUrl();
public static final String TENANT_EMAIL = "tenant@thingsboard.org";
public static final String TENANT_PASSWORD = "tenant";
public static final String ENTITY_NAME = "Az!@#$%^&*()_-+=~`" + getRandomNumber();
public static final String ROOT_RULE_CHAIN_NAME = "Root Rule Chain";
public static final String IMPORT_RULE_CHAIN_NAME = "Rule Chain from Import";
public static final String IMPORT_RULE_CHAIN_FILE_NAME = "forImport.json";
public static final String IMPORT_TXT_FILE_NAME = "forImport.txt";
public static final String EMPTY_IMPORT_MESSAGE = "No file selected";
public static final String EMPTY_RULE_CHAIN_MESSAGE = "Rule chain name should be specified!";
public static final String EMPTY_CUSTOMER_MESSAGE = "Customer title should be specified!";
public static final String DELETE_RULE_CHAIN_WITH_PROFILE_MESSAGE = "The rule chain referenced by the device profiles cannot be deleted!";
public static final String SAME_NAME_WARNING_CUSTOMER_MESSAGE = "Customer with such title already exists!";
public static final String PHONE_NUMBER_ERROR_MESSAGE = "Phone number is invalid or not possible";
}

77
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/DataProviderCredential.java

@ -0,0 +1,77 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.utils;
import org.testng.annotations.DataProvider;
import static org.thingsboard.server.msa.ui.base.AbstractBasePage.getRandomSymbol;
import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME;
public class DataProviderCredential {
private static final String SYMBOL = String.valueOf(getRandomSymbol());
private static final String NAME = ENTITY_NAME;
private static final String NUMBER = "1";
private static final String LONG_PHONE_NUMBER = "20155501231";
private static final String SHORT_PHONE_NUMBER = "201555011";
private static final String RULE_CHAIN_SECOND_WORD_NAME_PATH = "Rule";
private static final String CUSTOMER_SECOND_WORD_NAME_PATH = "Customer";
private static final String RULE_CHAIN_FIRST_WORD_NAME_PATH = "Root";
private static final String CUSTOMER_FIRST_WORD_NAME_PATH = "A";
@DataProvider
public static Object[][] ruleChainNameForSearchByFirstAndSecondWord() {
return new Object[][]{
{RULE_CHAIN_SECOND_WORD_NAME_PATH},
{RULE_CHAIN_FIRST_WORD_NAME_PATH}};
}
@DataProvider
public static Object[][] nameForSearchBySymbolAndNumber() {
return new Object[][]{
{NAME, ENTITY_NAME.split("`")[1]},
{NAME, String.valueOf(getRandomSymbol())}};
}
@DataProvider
public static Object[][] nameForSort() {
return new Object[][]{
{NAME},
{SYMBOL},
{NUMBER}};
}
@DataProvider
public static Object[][] nameForAllSort() {
return new Object[][]{
{NAME, SYMBOL, NUMBER}};
}
@DataProvider
public static Object[][] incorrectPhoneNumber() {
return new Object[][]{
{LONG_PHONE_NUMBER},
{SHORT_PHONE_NUMBER},
{ENTITY_NAME}};
}
@DataProvider
public static Object[][] customerNameForSearchByFirstAndSecondWord() {
return new Object[][]{
{CUSTOMER_FIRST_WORD_NAME_PATH},
{CUSTOMER_SECOND_WORD_NAME_PATH}};
}
}

34
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/EntityPrototypes.java

@ -0,0 +1,34 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.msa.ui.utils;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.rule.RuleChain;
public class EntityPrototypes {
public static Customer defaultCustomerPrototype(String entityName){
Customer customer = new Customer();
customer.setTitle(entityName);
return customer;
}
public static RuleChain defaultRuleChainPrototype(String entityName){
RuleChain ruleChain = new RuleChain();
ruleChain.setName(entityName);
return ruleChain;
}
}

50
msa/black-box-tests/src/test/resources/all.xml

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright © 2016-2022 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="All tests">
<listeners>
<listener class-name="org.thingsboard.server.msa.ui.listeners.RetryTestListener"/>
</listeners>
<test verbose="2" name="Connectivity tests" preserve-order="false">
<packages>
<package name="org.thingsboard.server.msa.connectivity" />
</packages>
</test>
<test name="Smoke rule chains tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.ruleChainsSmoke"/>
</packages>
</test>
<test name="Smoke customers tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.customerSmoke"/>
</packages>
</test>
</suite>

2
msa/black-box-tests/src/test/resources/allure.properties

@ -0,0 +1,2 @@
allure.results.directory=target/allure-results
allure.output.directory=target/allure-results

2
msa/black-box-tests/src/test/resources/testNG.xml → msa/black-box-tests/src/test/resources/connectivity.xml

@ -18,7 +18,7 @@
-->
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Black-box tests">
<suite name="Connectivity tests">
<test verbose="2" name="Connectivity tests" preserve-order="false">
<packages>
<package name="org.thingsboard.server.msa.connectivity" />

37
msa/black-box-tests/src/test/resources/docker-selenium.yml

@ -0,0 +1,37 @@
#
# Copyright © 2016-2022 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3'
services:
selenium-chrome:
restart: always
image: selenium/standalone-chrome
ports:
- '4444:4444'
- '7900:7900'
shm_size: 2gb
environment:
SE_NODE_MAX_SESSIONS: 8
SE_NODE_OVERRIDE_MAX_SESSIONS: 'true'
SE_NODE_SESSION_TIMEOUT: 5000
SE_SCREEN_WIDTH: 1920
SE_SCREEN_HEIGHT: 1080
SE_SCREEN_DEPTH: 24
SE_SCREEN_DPI: 74
extra_hosts:
- "host.docker.internal:172.17.0.1"

20
msa/black-box-tests/src/test/resources/forImport.json

@ -0,0 +1,20 @@
{
"ruleChain": {
"additionalInfo": {
"description": ""
},
"name": "Rule Chain from Import",
"type": "CORE",
"firstRuleNodeId": null,
"root": false,
"debugMode": false,
"configuration": null,
"externalId": null
},
"metadata": {
"firstNodeIndex": null,
"nodes": [],
"connections": null,
"ruleChainConnections": null
}
}

16
msa/black-box-tests/src/test/resources/forImport.txt

@ -0,0 +1,16 @@
====
Copyright © 2016-2022 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
====

35
msa/black-box-tests/src/test/resources/smokesCustomer.xml

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright © 2016-2022 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Customer Smoke Tests">
<listeners>
<listener class-name="org.thingsboard.server.msa.ui.listeners.RetryTestListener"/>
</listeners>
<test name="Customer ui smoke tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.customerSmoke"/>
</packages>
</test>
</suite>

35
msa/black-box-tests/src/test/resources/smokesRuleChain.xml

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright © 2016-2022 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Rule Chain Smoke Tests">
<listeners>
<listener class-name="org.thingsboard.server.msa.ui.listeners.RetryTestListener"/>
</listeners>
<test name="Rule Chain ui smoke tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.ruleChainsSmoke"/>
</packages>
</test>
</suite>

45
msa/black-box-tests/src/test/resources/uiTests.xml

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright © 2016-2022 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="UI smoke tests">
<listeners>
<listener class-name="org.thingsboard.server.msa.ui.listeners.RetryTestListener"/>
</listeners>
<test name="Smoke rule chains tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.ruleChainsSmoke"/>
</packages>
</test>
<test name="Smoke customers tests">
<groups>
<run>
<exclude name="broken"/>
</run>
</groups>
<packages>
<package name="org.thingsboard.server.msa.ui.tests.customerSmoke"/>
</packages>
</test>
</suite>

30
pom.xml

@ -54,7 +54,7 @@
<cassandra.version>4.15.0</cassandra.version>
<metrics.version>4.0.5</metrics.version>
<cassandra-all.version>3.11.14</cassandra-all.version>
<guava.version>30.0-jre</guava.version>
<guava.version>31.1-jre</guava.version>
<caffeine.version>2.6.1</caffeine.version>
<commons-lang3.version>3.4</commons-lang3.version>
<commons-codec.version>1.15</commons-codec.version>
@ -145,6 +145,10 @@
<jgit.version>6.1.0.202203080745-r</jgit.version>
<exp4j.version>0.4.8</exp4j.version>
<aerogear-otp.version>1.0.0</aerogear-otp.version>
<selenium.version>4.6.0</selenium.version>
<webdrivermanager.version>5.2.0</webdrivermanager.version>
<allure-testng.version>2.19.0</allure-testng.version>
<allure-maven.version>2.8</allure-maven.version>
</properties>
<modules>
@ -1657,6 +1661,30 @@
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>${webdrivermanager.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>${allure-testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>${allure-maven.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>

1
ui-ngx/src/app/core/api/widget-subscription.ts

@ -204,6 +204,7 @@ export class WidgetSubscription implements IWidgetSubscription {
this.timeWindow = {};
this.useDashboardTimewindow = options.useDashboardTimewindow;
this.useTimewindow = true;
this.onTimewindowChangeFunction = options.onTimewindowChangeFunction || ((timewindow) => timewindow);
if (this.useDashboardTimewindow) {
this.timeWindowConfig = deepClone(options.dashboardTimewindow);
} else {

Loading…
Cancel
Save