From 1278a63ec75212af091a3da09026ac4c1e09ed1e Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Mon, 27 Jan 2020 19:23:49 +0300 Subject: [PATCH 01/38] extracted ISettingsFile and added tests --- pom.xml | 5 + .../core/application/AqualityModule.java | 17 +++ .../core/utilities/ISettingsFile.java | 17 +++ .../core/utilities/JsonSettingsFile.java | 115 +++++++++++++++++ .../selenium/core/utilities/ResourceFile.java | 52 ++++++++ src/main/resources/settings.json | 2 +- .../tests/utilities/SettingsFileTests.java | 121 ++++++++++++++++++ src/test/resources/TestSuite.xml | 1 + src/test/resources/settings.json | 15 +++ src/test/resources/settings.jsontest.json | 18 +++ 10 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 src/main/java/aquality/selenium/core/utilities/ISettingsFile.java create mode 100644 src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java create mode 100644 src/main/java/aquality/selenium/core/utilities/ResourceFile.java create mode 100644 src/test/java/tests/utilities/SettingsFileTests.java create mode 100644 src/test/resources/settings.json create mode 100644 src/test/resources/settings.jsontest.json diff --git a/pom.xml b/pom.xml index 0a69348..60bd6df 100644 --- a/pom.xml +++ b/pom.xml @@ -84,6 +84,11 @@ guice 4.2.2 + + com.fasterxml.jackson.core + jackson-databind + 2.10.1 + org.seleniumhq.selenium selenium-remote-driver diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index f0c3d70..634bdf9 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,7 +1,10 @@ package aquality.selenium.core.application; +import aquality.selenium.core.utilities.ISettingsFile; +import aquality.selenium.core.utilities.JsonSettingsFile; import com.google.inject.AbstractModule; import aquality.selenium.core.logging.Logger; +import com.google.inject.Provides; /** * Describes all dependencies which is registered for the project. @@ -15,4 +18,18 @@ public class AqualityModule extends AbstractModule { protected void configure() { bind(Logger.class).toInstance(Logger.getInstance()); } + + /** + * Provides default {@link ISettingsFile}. with settings. + * Default value is settings.json. + * You are able to override this path, by setting environment variable 'profile'. + * In this case, settings file will be settings.{profile}.json. + * + * @return An instance of settings. + */ + @Provides + protected ISettingsFile getSettings() { + String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json"; + return new JsonSettingsFile(settingsProfile); + } } \ No newline at end of file diff --git a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java new file mode 100644 index 0000000..b807677 --- /dev/null +++ b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java @@ -0,0 +1,17 @@ +package aquality.selenium.core.utilities; + +import java.util.List; +import java.util.Map; + +public interface ISettingsFile { + + Object getValue(String jsonPath); + + List getList(String jsonPath); + + Map getMap(String jsonPath); + + String getContent(); + + boolean isValuePresent(String path); +} diff --git a/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java b/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java new file mode 100644 index 0000000..295200d --- /dev/null +++ b/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java @@ -0,0 +1,115 @@ +package aquality.selenium.core.utilities; + +import aquality.selenium.core.logging.Logger; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; + +public class JsonSettingsFile implements ISettingsFile { + + private final ObjectMapper mapper = new ObjectMapper(); + private final String fileCanonicalPath; + private final String content; + + public JsonSettingsFile(File file) throws IOException { + this.content = getFileContent(file.getCanonicalPath()); + fileCanonicalPath = file.getCanonicalPath(); + } + + public JsonSettingsFile(String resourceName) { + ResourceFile resourceFile = new ResourceFile(resourceName); + this.content = resourceFile.getFileContent(); + this.fileCanonicalPath = resourceFile.getFileCanonicalPath(); + } + + @Override + public Object getValue(String jsonPath) { + return getEnvValueOrDefault(jsonPath); + } + + private Object getEnvValueOrDefault(String jsonPath) { + String envVar = getEnvValue(jsonPath); + if (envVar == null) { + JsonNode node = getJsonNode(jsonPath); + if (node.isBoolean()) { + return node.asBoolean(); + } else if (node.isLong()) { + return node.asLong(); + } else if (node.isInt()) { + return node.asInt(); + } else { + return node.asText(); + } + } + + return envVar; + } + + private String getEnvValue(String jsonPath) { + String key = jsonPath.replace("/", ".").substring(1, jsonPath.length()); + String envVar = System.getProperty(key); + if (envVar != null) { + Logger.getInstance().debug(String.format("***** Using variable passed from environment %1$s=%2$s", key, envVar)); + } + + return envVar; + } + + @Override + public List getList(String jsonPath) { + List list = new ArrayList<>(); + String envVar = getEnvValue(jsonPath); + if (envVar != null) { + Arrays.stream(envVar.split(",")).forEach(element -> list.add(element.trim())); + } else { + getJsonNode(jsonPath).elements().forEachRemaining(node -> list.add(node.asText())); + } + + return list; + } + + @Override + public Map getMap(String jsonPath) { + Iterator> iterator = getJsonNode(jsonPath).fields(); + final Map result = new HashMap<>(); + iterator.forEachRemaining(entry -> result.put(entry.getKey(), getValue(jsonPath + "/" + entry.getKey()))); + return result; + } + + private JsonNode getJsonNode(String jsonPath) { + try { + JsonNode node = mapper.readTree(getContent()); + return node.at(jsonPath); + } catch (IOException e) { + throw new UncheckedIOException(String.format("Json field by json-path %1$s was not found in the file %2$s", jsonPath, getContent()), e); + } + } + + private String getFileContent(String filename) { + try { + return new String(Files.readAllBytes(Paths.get(filename))); + } catch (IOException e) { + throw new UncheckedIOException(String.format("Content of file %1$s can't be read as String", filename), e); + } + } + + public String getContent() { + return content; + } + + @Override + public boolean isValuePresent(String path) { + String value = getValue(path).toString().trim(); + return !value.isEmpty(); + } + + public String getFileCanonicalPath() { + return fileCanonicalPath; + } +} diff --git a/src/main/java/aquality/selenium/core/utilities/ResourceFile.java b/src/main/java/aquality/selenium/core/utilities/ResourceFile.java new file mode 100644 index 0000000..427fc92 --- /dev/null +++ b/src/main/java/aquality/selenium/core/utilities/ResourceFile.java @@ -0,0 +1,52 @@ +package aquality.selenium.core.utilities; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UncheckedIOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.stream.Collectors; + +class ResourceFile { + private final String resourceName; + private final String fileCanonicalPath; + private final String fileContent; + + ResourceFile(String resourceName) { + this.resourceName = resourceName; + fileCanonicalPath = getResourcePath(resourceName); + fileContent = getResourceFileContent(resourceName); + } + + String getResourceFileContent(final String resourceName) { + InputStreamReader inputStream = new InputStreamReader(Objects.requireNonNull(JsonSettingsFile.class.getClassLoader().getResourceAsStream(resourceName)), StandardCharsets.UTF_8); + try (BufferedReader br = new BufferedReader(inputStream)) { + return br.lines().collect(Collectors.joining(System.lineSeparator())); + } catch (IOException e) { + throw new UncheckedIOException(String.format("Reading of resource file '%1$s' was failed", resourceName), e); + } + } + + static String getResourcePath(final String resourceName) { + try { + URL resourceURL = JsonSettingsFile.class.getClassLoader().getResource(resourceName); + return Objects.requireNonNull(resourceURL).getPath(); + } catch (NullPointerException e) { + throw new IllegalArgumentException(String.format("Resource file %1$s was not found or cannot be loaded", resourceName), e); + } + } + + public String getResourceName() { + return resourceName; + } + + String getFileCanonicalPath() { + return fileCanonicalPath; + } + + String getFileContent() { + return fileContent; + } +} diff --git a/src/main/resources/settings.json b/src/main/resources/settings.json index 2c63c08..7a73a41 100644 --- a/src/main/resources/settings.json +++ b/src/main/resources/settings.json @@ -1,2 +1,2 @@ { -} +} \ No newline at end of file diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java new file mode 100644 index 0000000..e1a51d0 --- /dev/null +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -0,0 +1,121 @@ +package tests.utilities; + +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import tests.application.TestModule; +import java.io.File; +import java.io.IOException; +import java.util.*; + +import static org.testng.Assert.*; + +public class SettingsFileTests { + private static final String timeoutPollingIntervalPath = "/timeouts/timeoutPollingInterval"; + private static final String timeoutPollingIntervalKey = "timeouts.timeoutPollingInterval"; + private static final String languageEnvKey = "logger.language"; + private static final String argumentsEnvKey = "arguments.start"; + private static final String profile = "jsontest"; + private static final String profileKey = "profile"; + private static final String fileName = String.format("settings.%s.json", profile); + private static final String defaultFileName = "settings.json"; + private ISettingsFile jsonSettingsFile; + private static final Map expectedLanguages = new HashMap() {{ + put("language", "ru"); + }}; + + @BeforeMethod + public void before() { + System.setProperty(profileKey, profile); + jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); + } + + @Test + public void testShouldBePossibleToGetDefaultContent() throws IOException { + System.clearProperty(profileKey); + CustomAqualityServices.initInjector(new TestModule()); + jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); + + String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(defaultFileName).getFile()), Charsets.UTF_8).read(); + String actualContent = jsonSettingsFile.getContent(); + assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", defaultFileName)); + } + + @Test + public void testShouldBePossibleToGetContent() throws IOException { + String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(fileName).getFile()), Charsets.UTF_8).read(); + String actualContent = jsonSettingsFile.getContent(); + assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", fileName)); + } + + @Test + public void testShouldBePossibleToGetValue() { + String languagePath = "/logger/language"; + String languageKey = "language"; + + String language = jsonSettingsFile.getValue(languagePath).toString(); + assertEquals(language, expectedLanguages.get(languageKey), String.format("Logger language in settings file '%s' should be read correctly", fileName)); + + String newLang = "newLang"; + System.setProperty(languageEnvKey, newLang); + language = jsonSettingsFile.getValue(languagePath).toString(); + assertEquals(language, newLang, String.format("Logger language in settings file '%s' should be overridden with environment variable", fileName)); + } + + @Test + public void testShouldBePossibleToGetListOfValues() { + String argumentsPath = "/arguments/start"; + List expectedArguments = Arrays.asList("first", "second"); + + List arguments = jsonSettingsFile.getList(argumentsPath); + assertNotNull(arguments); + assertEquals(arguments, expectedArguments, String.format("List of values in settings file '%s' should be read correctly", fileName)); + + expectedArguments = Arrays.asList("firstNew", "secondNew"); + String newArgs = "firstNew,secondNew"; + System.setProperty(argumentsEnvKey, newArgs); + arguments = jsonSettingsFile.getList(argumentsPath); + assertNotNull(arguments); + assertEquals(arguments, expectedArguments, String.format("Value in list in settings file '%s' be overridden with environment variable", fileName)); + } + + @Test + public void testShouldBePossibleToGetMap() { + String loggerPath = "/logger"; + + Map languages = jsonSettingsFile.getMap(loggerPath); + assertNotNull(languages); + assertEquals(languages, expectedLanguages, String.format("Map of values in settings file '%s' should be read correctly", fileName)); + + String newLanguageValue = "newLangMap"; + Map expectedLanguages = new HashMap() {{ + put("language", newLanguageValue); + }}; + System.setProperty(languageEnvKey, newLanguageValue); + languages = jsonSettingsFile.getMap(loggerPath); + assertNotNull(languages); + assertEquals(languages, expectedLanguages, String.format("Map of values in settings file '%s' should be overridden with environment variable", fileName)); + } + + @Test + public void testShouldBePossibleToCheckIsValuePresent() { + boolean isTimeoutsPresent = jsonSettingsFile.isValuePresent(timeoutPollingIntervalPath); + assertTrue(isTimeoutsPresent, String.format("%s value should be present in settings file '%s'", timeoutPollingIntervalPath, fileName)); + + String wrongPath = "/blabla"; + boolean isWrongPathPresent = jsonSettingsFile.isValuePresent(wrongPath); + assertFalse(isWrongPathPresent, String.format("%s value should not be present in settings file '%s'", wrongPath, fileName)); + } + + @AfterMethod + public void after() { + System.clearProperty(profileKey); + System.clearProperty(languageEnvKey); + System.clearProperty(timeoutPollingIntervalKey); + System.clearProperty(argumentsEnvKey); + } +} \ No newline at end of file diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index b5e7d8e..76ab3f9 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -13,6 +13,7 @@ + \ No newline at end of file diff --git a/src/test/resources/settings.json b/src/test/resources/settings.json new file mode 100644 index 0000000..e2b7382 --- /dev/null +++ b/src/test/resources/settings.json @@ -0,0 +1,15 @@ +{ + "timeouts": { + "timeoutImplicit": 0, + "timeoutCondition": 30, + "timeoutPollingInterval": 300, + "timeoutCommand": 60 + }, + "retry": { + "number": 2, + "pollingInterval": 300 + }, + "logger": { + "language": "en" + } +} \ No newline at end of file diff --git a/src/test/resources/settings.jsontest.json b/src/test/resources/settings.jsontest.json new file mode 100644 index 0000000..bd0c737 --- /dev/null +++ b/src/test/resources/settings.jsontest.json @@ -0,0 +1,18 @@ +{ + "timeouts": { + "timeoutImplicit": 1000, + "timeoutCondition": 1000, + "timeoutPollingInterval": 1000, + "timeoutCommand": 1000 + }, + "retry": { + "number": 1000, + "pollingInterval": 1000 + }, + "logger": { + "language": "ru" + }, + "arguments": { + "start": ["first","second"] + } +} \ No newline at end of file From 1c72731c2379af305d33ee5838b6093dcb66c61f Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 10:14:42 +0300 Subject: [PATCH 02/38] added documentation for ISettingsFile --- .../core/utilities/ISettingsFile.java | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java index b807677..780428d 100644 --- a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java +++ b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java @@ -3,15 +3,47 @@ import java.util.List; import java.util.Map; +/** + * Describes reader of settings file. + */ public interface ISettingsFile { - Object getValue(String jsonPath); + /** + * Gets value from settings file. + * + * @param path Path to the value. Depending on file format, it can be jsonPath, xpath etc. + * @return Value. + */ + Object getValue(String path); - List getList(String jsonPath); + /** + * Gets list of values from settings file. + * + * @param path Path to the value. Depending on file format, it can be jsonPath, xpath etc. + * @return List of values. + */ + List getList(String path); - Map getMap(String jsonPath); + /** + * Gets map of keys and values from settings file. + * + * @param path Path to the value. Depending on file format, it can be jsonPath, xpath etc. + * @return Map of keys and values. + */ + Map getMap(String path); + /** + * Gets content of settings file. + * + * @return Content of settings file as string. + */ String getContent(); + /** + * Checks if value exists in settings. + * + * @param path Path to the values. Depending on file format, it can be jsonPath, xpath etc. + * @return True if exists, false otherwise. + */ boolean isValuePresent(String path); } From 1f0602aec07be09c5dabba800bf7503a6d2a1d5d Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 12:15:54 +0300 Subject: [PATCH 03/38] extracted ILoggerConfiguration --- .../core/application/AqualityModule.java | 3 ++ .../configurations/ILoggerConfiguration.java | 16 +++++++++ .../configurations/LoggerConfiguration.java | 20 +++++++++++ .../core/localization/SupportedLanguage.java | 5 +++ .../configurations/EnvConfigurationTests.java | 33 +++++++++++++++++++ .../LoggerConfigurationTests.java | 16 +++++++++ .../ProfileConfigurationTests.java | 33 +++++++++++++++++++ src/test/resources/TestSuite.xml | 3 ++ src/test/resources/settings.custom.json | 15 +++++++++ 9 files changed, 144 insertions(+) create mode 100644 src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java create mode 100644 src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java create mode 100644 src/main/java/aquality/selenium/core/localization/SupportedLanguage.java create mode 100644 src/test/java/tests/configurations/EnvConfigurationTests.java create mode 100644 src/test/java/tests/configurations/LoggerConfigurationTests.java create mode 100644 src/test/java/tests/configurations/ProfileConfigurationTests.java create mode 100644 src/test/resources/settings.custom.json diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 634bdf9..4f2fa6b 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,5 +1,7 @@ package aquality.selenium.core.application; +import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.configurations.LoggerConfiguration; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; import com.google.inject.AbstractModule; @@ -17,6 +19,7 @@ public class AqualityModule extends AbstractModule { @Override protected void configure() { bind(Logger.class).toInstance(Logger.getInstance()); + bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); } /** diff --git a/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java b/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java new file mode 100644 index 0000000..741c72d --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java @@ -0,0 +1,16 @@ +package aquality.selenium.core.configurations; + +import aquality.selenium.core.localization.SupportedLanguage; + +/** + * Describes logger configuration. + */ +public interface ILoggerConfiguration { + + /** + * Gets language of framework. + * + * @return Supported language. + */ + SupportedLanguage getLanguage(); +} diff --git a/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java b/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java new file mode 100644 index 0000000..3f57ab8 --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java @@ -0,0 +1,20 @@ +package aquality.selenium.core.configurations; + +import aquality.selenium.core.localization.SupportedLanguage; +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; + +public class LoggerConfiguration implements ILoggerConfiguration{ + + private final ISettingsFile settingsFile; + + @Inject + public LoggerConfiguration(ISettingsFile settingsFile){ + this.settingsFile = settingsFile; + } + + @Override + public SupportedLanguage getLanguage() { + return SupportedLanguage.valueOf(settingsFile.getValue("/logger/language").toString().toUpperCase()); + } +} diff --git a/src/main/java/aquality/selenium/core/localization/SupportedLanguage.java b/src/main/java/aquality/selenium/core/localization/SupportedLanguage.java new file mode 100644 index 0000000..1ff75cc --- /dev/null +++ b/src/main/java/aquality/selenium/core/localization/SupportedLanguage.java @@ -0,0 +1,5 @@ +package aquality.selenium.core.localization; + +public enum SupportedLanguage { + EN,RU +} diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java new file mode 100644 index 0000000..e4fd60f --- /dev/null +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -0,0 +1,33 @@ +package tests.configurations; + +import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.localization.SupportedLanguage; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import tests.application.TestModule; + +import static org.testng.Assert.assertEquals; + +public class EnvConfigurationTests { + + private static final String languageKey = "logger.language"; + + @BeforeMethod + public void before(){ + System.setProperty(languageKey, "ru"); + CustomAqualityServices.initInjector(new TestModule()); + } + + @Test + public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { + SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, SupportedLanguage.RU, "Current language should be overridden with env variable"); + } + + @AfterMethod + public void after(){ + System.clearProperty(languageKey); + } +} \ No newline at end of file diff --git a/src/test/java/tests/configurations/LoggerConfigurationTests.java b/src/test/java/tests/configurations/LoggerConfigurationTests.java new file mode 100644 index 0000000..1263d91 --- /dev/null +++ b/src/test/java/tests/configurations/LoggerConfigurationTests.java @@ -0,0 +1,16 @@ +package tests.configurations; + +import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.localization.SupportedLanguage; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import static org.testng.Assert.assertEquals; + +public class LoggerConfigurationTests { + + @Test + public void testShouldBePossibleToGetLanguage() { + SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, SupportedLanguage.EN, "Current language should be got from logger configuration"); + } +} \ No newline at end of file diff --git a/src/test/java/tests/configurations/ProfileConfigurationTests.java b/src/test/java/tests/configurations/ProfileConfigurationTests.java new file mode 100644 index 0000000..f8b32b8 --- /dev/null +++ b/src/test/java/tests/configurations/ProfileConfigurationTests.java @@ -0,0 +1,33 @@ +package tests.configurations; + +import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.localization.SupportedLanguage; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import tests.application.TestModule; + +import static org.testng.Assert.assertEquals; + +public class ProfileConfigurationTests { + + private static final String profileKey = "profile"; + private static final String profile = "custom"; + + @BeforeMethod + public void before(){ + System.setProperty(profileKey, profile); + } + + @Test + public void testShouldBePossibleToGetLanguageFromNewSettingsFile() { + SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, SupportedLanguage.RU, String.format("Current language should be got from %s profile", profile)); + } + + @AfterMethod + public void after(){ + System.clearProperty(profileKey); + } +} \ No newline at end of file diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index 76ab3f9..7e76b43 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -4,6 +4,7 @@ + @@ -14,6 +15,8 @@ + + \ No newline at end of file diff --git a/src/test/resources/settings.custom.json b/src/test/resources/settings.custom.json new file mode 100644 index 0000000..7a40015 --- /dev/null +++ b/src/test/resources/settings.custom.json @@ -0,0 +1,15 @@ +{ + "timeouts": { + "timeoutImplicit": 1, + "timeoutCondition": 300, + "timeoutPollingInterval": 3000, + "timeoutCommand": 600 + }, + "retry": { + "number": 20, + "pollingInterval": 3000 + }, + "logger": { + "language": "ru" + } +} \ No newline at end of file From aee91516cd33c4201b9a73441368fdfa2cbac31e Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 15:23:28 +0300 Subject: [PATCH 04/38] extracted ITimeoutConfiguration --- .../core/application/AqualityModule.java | 3 + .../configurations/ITimeoutConfiguration.java | 35 +++++++++++ .../configurations/TimeoutConfiguration.java | 58 +++++++++++++++++++ .../configurations/EnvConfigurationTests.java | 38 ++++++++++-- .../TimeoutConfigurationTests.java | 19 ++++++ src/test/resources/TestSuite.xml | 1 + 6 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 src/main/java/aquality/selenium/core/configurations/ITimeoutConfiguration.java create mode 100644 src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java create mode 100644 src/test/java/tests/configurations/TimeoutConfigurationTests.java diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 4f2fa6b..f4b92b1 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,7 +1,9 @@ package aquality.selenium.core.application; import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.configurations.ITimeoutConfiguration; import aquality.selenium.core.configurations.LoggerConfiguration; +import aquality.selenium.core.configurations.TimeoutConfiguration; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; import com.google.inject.AbstractModule; @@ -20,6 +22,7 @@ public class AqualityModule extends AbstractModule { protected void configure() { bind(Logger.class).toInstance(Logger.getInstance()); bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); + bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); } /** diff --git a/src/main/java/aquality/selenium/core/configurations/ITimeoutConfiguration.java b/src/main/java/aquality/selenium/core/configurations/ITimeoutConfiguration.java new file mode 100644 index 0000000..bfc69c5 --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/ITimeoutConfiguration.java @@ -0,0 +1,35 @@ +package aquality.selenium.core.configurations; + +/** + * Provides timeouts configuration. + */ +public interface ITimeoutConfiguration { + + /** + * Gets WedDriver ImplicitWait timeout. + * + * @return ImplicitWait timeout. + */ + long getImplicit(); + + /** + * Gets default ConditionalWait timeout. + * + * @return ConditionalWait timeout. + */ + long getCondition(); + + /** + * Gets ConditionalWait polling interval. + * + * @return polling interval. + */ + long getPollingInterval(); + + /** + * Gets Command timeout. + * + * @return Command timeout. + */ + long getCommand(); +} diff --git a/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java b/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java new file mode 100644 index 0000000..34088ce --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java @@ -0,0 +1,58 @@ +package aquality.selenium.core.configurations; + +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; + +public class TimeoutConfiguration implements ITimeoutConfiguration{ + + private final ISettingsFile settingsFile; + private final long condition; + private final long pollInterval; + private final long implicit; + private final long command; + + @Inject + public TimeoutConfiguration(ISettingsFile settingsFile) { + this.settingsFile = settingsFile; + condition = getTimeout(TIMEOUT.CONDITION); + pollInterval = getTimeout(TIMEOUT.POLL_INTERVAL); + implicit = getTimeout(TIMEOUT.IMPLICIT); + command = getTimeout(TIMEOUT.COMMAND); + } + + private long getTimeout(TIMEOUT timeout){ + return Long.valueOf(settingsFile.getValue("/timeouts/" + timeout.getKey()).toString()); + } + + public long getImplicit(){ + return implicit; + } + + public long getCondition(){ + return condition; + } + + public long getPollingInterval(){ + return pollInterval; + } + + public long getCommand(){ + return command; + } + + private enum TIMEOUT { + IMPLICIT("timeoutImplicit"), + CONDITION("timeoutCondition"), + POLL_INTERVAL("timeoutPollingInterval"), + COMMAND("timeoutCommand"); + + private String key; + TIMEOUT(String key){ + this.key = key; + } + + private String getKey(){ + return key; + } + } +} diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index e4fd60f..cef8df9 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -1,7 +1,11 @@ package tests.configurations; +import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.configurations.ITimeoutConfiguration; import aquality.selenium.core.localization.SupportedLanguage; +import com.google.inject.Injector; +import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -13,21 +17,47 @@ public class EnvConfigurationTests { private static final String languageKey = "logger.language"; + private static final String languageValue = "ru"; + private static final String conditionTimeoutKey = "timeouts.timeoutCondition"; + private static final String newTimeoutValue = "10000"; + private Injector injector; @BeforeMethod - public void before(){ - System.setProperty(languageKey, "ru"); + public void before() { + System.setProperty(languageKey, languageValue); + System.setProperty(conditionTimeoutKey, newTimeoutValue); CustomAqualityServices.initInjector(new TestModule()); + injector = CustomAqualityServices.getInjector(); } @Test public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { - SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); + SupportedLanguage language = injector.getInstance(ILoggerConfiguration.class).getLanguage(); assertEquals(language, SupportedLanguage.RU, "Current language should be overridden with env variable"); } + @Test + public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { + long conditionTimeout = injector.getInstance(ITimeoutConfiguration.class).getCondition(); + assertEquals(conditionTimeout, Long.parseLong(newTimeoutValue), "Condition timeout should be overridden with env variable"); + } + + @Test + public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { + System.setProperty(conditionTimeoutKey, languageValue); + try { + CustomAqualityServices.initInjector(new TestModule()); + CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class).getCommand(); + } catch (Exception e) { + Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); + Assert.assertTrue(e.getMessage().contains("NumberFormatException")); + } + } + @AfterMethod - public void after(){ + public void after() { System.clearProperty(languageKey); + System.clearProperty(conditionTimeoutKey); + CustomAqualityServices.initInjector(new AqualityModule()); } } \ No newline at end of file diff --git a/src/test/java/tests/configurations/TimeoutConfigurationTests.java b/src/test/java/tests/configurations/TimeoutConfigurationTests.java new file mode 100644 index 0000000..77e2807 --- /dev/null +++ b/src/test/java/tests/configurations/TimeoutConfigurationTests.java @@ -0,0 +1,19 @@ +package tests.configurations; + +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; + +import static org.testng.Assert.assertEquals; + +public class TimeoutConfigurationTests { + + @Test + public void testShouldBePossibleToGetLanguage() { + ITimeoutConfiguration timeoutConfiguration = CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class); + assertEquals(timeoutConfiguration.getCommand(), 60, "Command timeout should be got"); + assertEquals(timeoutConfiguration.getCondition(), 30, "Condition timeout should be got"); + assertEquals(timeoutConfiguration.getImplicit(), 0, "Implicit timeout should be got"); + assertEquals(timeoutConfiguration.getPollingInterval(), 300, "Polling interval should be got"); + } +} \ No newline at end of file diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index 7e76b43..029d98b 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -5,6 +5,7 @@ + From 3ede916b918be186605cae021ba2d98a8ad7ce07 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 15:34:40 +0300 Subject: [PATCH 05/38] extracted IRetryConfiguration --- .../core/application/AqualityModule.java | 6 ++-- .../configurations/IRetryConfiguration.java | 21 ++++++++++++ .../configurations/RetryConfiguration.java | 25 ++++++++++++++ .../configurations/EnvConfigurationTests.java | 34 +++++++++++++++---- .../RetryConfigurationTests.java | 18 ++++++++++ src/test/resources/TestSuite.xml | 1 + 6 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 src/main/java/aquality/selenium/core/configurations/IRetryConfiguration.java create mode 100644 src/main/java/aquality/selenium/core/configurations/RetryConfiguration.java create mode 100644 src/test/java/tests/configurations/RetryConfigurationTests.java diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index f4b92b1..aef85d5 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,9 +1,6 @@ package aquality.selenium.core.application; -import aquality.selenium.core.configurations.ILoggerConfiguration; -import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.configurations.LoggerConfiguration; -import aquality.selenium.core.configurations.TimeoutConfiguration; +import aquality.selenium.core.configurations.*; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; import com.google.inject.AbstractModule; @@ -23,6 +20,7 @@ protected void configure() { bind(Logger.class).toInstance(Logger.getInstance()); bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); + bind(IRetryConfiguration.class).to(RetryConfiguration.class); } /** diff --git a/src/main/java/aquality/selenium/core/configurations/IRetryConfiguration.java b/src/main/java/aquality/selenium/core/configurations/IRetryConfiguration.java new file mode 100644 index 0000000..e6d9ca3 --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/IRetryConfiguration.java @@ -0,0 +1,21 @@ +package aquality.selenium.core.configurations; + +/** + * Describes retry configuration. + */ +public interface IRetryConfiguration { + + /** + * Gets the number of attempts during retry. + * + * @return Number of retry attempts. + */ + int getNumber(); + + /** + * Gets the polling interval used in retry. + * + * @return Polling interval for retry. + */ + long getPollingInterval(); +} diff --git a/src/main/java/aquality/selenium/core/configurations/RetryConfiguration.java b/src/main/java/aquality/selenium/core/configurations/RetryConfiguration.java new file mode 100644 index 0000000..4121510 --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/RetryConfiguration.java @@ -0,0 +1,25 @@ +package aquality.selenium.core.configurations; + +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; + +public class RetryConfiguration implements IRetryConfiguration { + private final int number; + private final long pollingInterval; + + @Inject + public RetryConfiguration(ISettingsFile settingsFile) { + this.number = Integer.parseInt(settingsFile.getValue("/retry/number").toString()); + this.pollingInterval = Long.parseLong(settingsFile.getValue("/retry/pollingInterval").toString()); + } + + @Override + public int getNumber() { + return number; + } + + @Override + public long getPollingInterval() { + return pollingInterval; + } +} diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index cef8df9..f63eaf6 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -2,6 +2,7 @@ import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.configurations.IRetryConfiguration; import aquality.selenium.core.configurations.ITimeoutConfiguration; import aquality.selenium.core.localization.SupportedLanguage; import com.google.inject.Injector; @@ -17,15 +18,17 @@ public class EnvConfigurationTests { private static final String languageKey = "logger.language"; - private static final String languageValue = "ru"; + private static final String newStringValue = "ru"; private static final String conditionTimeoutKey = "timeouts.timeoutCondition"; - private static final String newTimeoutValue = "10000"; + private static final String retryNumberKey = "retry.number"; + private static final String newIntValue = "10000"; private Injector injector; @BeforeMethod public void before() { - System.setProperty(languageKey, languageValue); - System.setProperty(conditionTimeoutKey, newTimeoutValue); + System.setProperty(languageKey, newStringValue); + System.setProperty(conditionTimeoutKey, newIntValue); + System.setProperty(retryNumberKey, newIntValue); CustomAqualityServices.initInjector(new TestModule()); injector = CustomAqualityServices.getInjector(); } @@ -39,12 +42,18 @@ public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { @Test public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { long conditionTimeout = injector.getInstance(ITimeoutConfiguration.class).getCondition(); - assertEquals(conditionTimeout, Long.parseLong(newTimeoutValue), "Condition timeout should be overridden with env variable"); + assertEquals(conditionTimeout, Long.parseLong(newIntValue), "Condition timeout should be overridden with env variable"); + } + + @Test + public void testShouldBePossibleToOverrideRetryConfigurationWithEnvVariable() { + int retryNumber = injector.getInstance(IRetryConfiguration.class).getNumber(); + assertEquals(retryNumber, Long.parseLong(newIntValue), "Number of retry attempts should be overridden with env variable"); } @Test public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { - System.setProperty(conditionTimeoutKey, languageValue); + System.setProperty(conditionTimeoutKey, newStringValue); try { CustomAqualityServices.initInjector(new TestModule()); CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class).getCommand(); @@ -54,10 +63,23 @@ public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { } } + @Test + public void testNumberFormatExceptionShouldBeThrownIfRetryConfigurationIsNotANumber() { + System.setProperty(retryNumberKey, newStringValue); + try { + CustomAqualityServices.initInjector(new TestModule()); + CustomAqualityServices.getInjector().getInstance(IRetryConfiguration.class).getNumber(); + } catch (Exception e) { + Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); + Assert.assertTrue(e.getMessage().contains("NumberFormatException")); + } + } + @AfterMethod public void after() { System.clearProperty(languageKey); System.clearProperty(conditionTimeoutKey); + System.clearProperty(retryNumberKey); CustomAqualityServices.initInjector(new AqualityModule()); } } \ No newline at end of file diff --git a/src/test/java/tests/configurations/RetryConfigurationTests.java b/src/test/java/tests/configurations/RetryConfigurationTests.java new file mode 100644 index 0000000..1104e8a --- /dev/null +++ b/src/test/java/tests/configurations/RetryConfigurationTests.java @@ -0,0 +1,18 @@ +package tests.configurations; + +import aquality.selenium.core.configurations.IRetryConfiguration; +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; + +import static org.testng.Assert.assertEquals; + +public class RetryConfigurationTests { + + @Test + public void testShouldBePossibleToGetRetryConfiguration() { + IRetryConfiguration retryConfiguration = CustomAqualityServices.getInjector().getInstance(IRetryConfiguration.class); + assertEquals(retryConfiguration.getNumber(), 2, "Number of retry attempts timeout should be got"); + assertEquals(retryConfiguration.getPollingInterval(), 300, "Polling interval of retrier should be got"); + } +} \ No newline at end of file diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index 029d98b..8aacb51 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -6,6 +6,7 @@ + From 4e2b14f10b9e0c3d17eb3bb7ab4fec8858f3afd1 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 15:35:32 +0300 Subject: [PATCH 06/38] renamed one test --- .../java/tests/configurations/TimeoutConfigurationTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/tests/configurations/TimeoutConfigurationTests.java b/src/test/java/tests/configurations/TimeoutConfigurationTests.java index 77e2807..e49966f 100644 --- a/src/test/java/tests/configurations/TimeoutConfigurationTests.java +++ b/src/test/java/tests/configurations/TimeoutConfigurationTests.java @@ -9,7 +9,7 @@ public class TimeoutConfigurationTests { @Test - public void testShouldBePossibleToGetLanguage() { + public void testShouldBePossibleToGetTimeoutConfiguration() { ITimeoutConfiguration timeoutConfiguration = CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class); assertEquals(timeoutConfiguration.getCommand(), 60, "Command timeout should be got"); assertEquals(timeoutConfiguration.getCondition(), 30, "Condition timeout should be got"); From d4ec6484f8c73dca451138019876097c67faf832 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 15:44:34 +0300 Subject: [PATCH 07/38] added empty end line and updated com.fasterxml.jackson.core to 2.10.2 --- pom.xml | 2 +- .../aquality/selenium/core/application/AqualityModule.java | 2 +- .../selenium/core/application/AqualityServices.java | 2 +- src/main/java/aquality/selenium/core/logging/Logger.java | 2 +- src/main/resources/settings.json | 2 +- src/test/java/tests/application/AqualityServicesTests.java | 2 +- src/test/java/tests/application/CustomAqualityServices.java | 2 +- src/test/java/tests/application/CustomDependency.java | 2 +- src/test/java/tests/application/ICustomDependency.java | 2 +- src/test/java/tests/application/TestModule.java | 2 +- src/test/java/tests/logger/LoggerTests.java | 2 +- src/test/java/tests/utilities/SettingsFileTests.java | 6 +++--- src/test/resources/settings.json | 2 +- src/test/resources/settings.jsontest.json | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 60bd6df..188a717 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ com.fasterxml.jackson.core jackson-databind - 2.10.1 + 2.10.2 org.seleniumhq.selenium diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 634bdf9..ea682b2 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -32,4 +32,4 @@ protected ISettingsFile getSettings() { String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json"; return new JsonSettingsFile(settingsProfile); } -} \ No newline at end of file +} diff --git a/src/main/java/aquality/selenium/core/application/AqualityServices.java b/src/main/java/aquality/selenium/core/application/AqualityServices.java index 2c12dad..a9bf69c 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityServices.java +++ b/src/main/java/aquality/selenium/core/application/AqualityServices.java @@ -41,4 +41,4 @@ protected static void initInjector(T module) { injectorContainer.remove(); injectorContainer.set(Guice.createInjector(module)); } -} \ No newline at end of file +} diff --git a/src/main/java/aquality/selenium/core/logging/Logger.java b/src/main/java/aquality/selenium/core/logging/Logger.java index 5fa89a4..28a8256 100644 --- a/src/main/java/aquality/selenium/core/logging/Logger.java +++ b/src/main/java/aquality/selenium/core/logging/Logger.java @@ -121,4 +121,4 @@ public void info(String key, Object... params) { public void debug(String key, Object... params) { log4J.get().debug(String.format(key, params)); } -} \ No newline at end of file +} diff --git a/src/main/resources/settings.json b/src/main/resources/settings.json index 7a73a41..2c63c08 100644 --- a/src/main/resources/settings.json +++ b/src/main/resources/settings.json @@ -1,2 +1,2 @@ { -} \ No newline at end of file +} diff --git a/src/test/java/tests/application/AqualityServicesTests.java b/src/test/java/tests/application/AqualityServicesTests.java index 54cfd1c..b2f08db 100644 --- a/src/test/java/tests/application/AqualityServicesTests.java +++ b/src/test/java/tests/application/AqualityServicesTests.java @@ -48,4 +48,4 @@ public void testShouldBePossibleToSetCustomInjector() { ICustomDependency customDependency = CustomAqualityServices.getInjector().getInstance(ICustomDependency.class); assertNotNull(customDependency, "ICustomDependency should be injected in custom module"); } -} \ No newline at end of file +} diff --git a/src/test/java/tests/application/CustomAqualityServices.java b/src/test/java/tests/application/CustomAqualityServices.java index 60472d8..606c979 100644 --- a/src/test/java/tests/application/CustomAqualityServices.java +++ b/src/test/java/tests/application/CustomAqualityServices.java @@ -16,4 +16,4 @@ public static Injector getInjector() { public static void initInjector(T module) { AqualityServices.initInjector(module); } -} \ No newline at end of file +} diff --git a/src/test/java/tests/application/CustomDependency.java b/src/test/java/tests/application/CustomDependency.java index 917af85..22711be 100644 --- a/src/test/java/tests/application/CustomDependency.java +++ b/src/test/java/tests/application/CustomDependency.java @@ -1,4 +1,4 @@ package tests.application; class CustomDependency implements ICustomDependency { -} \ No newline at end of file +} diff --git a/src/test/java/tests/application/ICustomDependency.java b/src/test/java/tests/application/ICustomDependency.java index 2540b60..8227f68 100644 --- a/src/test/java/tests/application/ICustomDependency.java +++ b/src/test/java/tests/application/ICustomDependency.java @@ -1,4 +1,4 @@ package tests.application; interface ICustomDependency { -} \ No newline at end of file +} diff --git a/src/test/java/tests/application/TestModule.java b/src/test/java/tests/application/TestModule.java index 02e1905..a1e6d7e 100644 --- a/src/test/java/tests/application/TestModule.java +++ b/src/test/java/tests/application/TestModule.java @@ -9,4 +9,4 @@ protected void configure() { super.configure(); bind(ICustomDependency.class).to(CustomDependency.class); } -} \ No newline at end of file +} diff --git a/src/test/java/tests/logger/LoggerTests.java b/src/test/java/tests/logger/LoggerTests.java index 1e7077b..8963a42 100644 --- a/src/test/java/tests/logger/LoggerTests.java +++ b/src/test/java/tests/logger/LoggerTests.java @@ -170,4 +170,4 @@ private File getRandomAppenderFile() { private void removeFileAppenderFromLogger() { logger.removeAppender(appender); } -} \ No newline at end of file +} diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index e1a51d0..76466ca 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -40,14 +40,14 @@ public void testShouldBePossibleToGetDefaultContent() throws IOException { CustomAqualityServices.initInjector(new TestModule()); jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); - String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(defaultFileName).getFile()), Charsets.UTF_8).read(); + String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(defaultFileName).getFile()), Charsets.UTF_8).read().trim(); String actualContent = jsonSettingsFile.getContent(); assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", defaultFileName)); } @Test public void testShouldBePossibleToGetContent() throws IOException { - String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(fileName).getFile()), Charsets.UTF_8).read(); + String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(fileName).getFile()), Charsets.UTF_8).read().trim(); String actualContent = jsonSettingsFile.getContent(); assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", fileName)); } @@ -118,4 +118,4 @@ public void after() { System.clearProperty(timeoutPollingIntervalKey); System.clearProperty(argumentsEnvKey); } -} \ No newline at end of file +} diff --git a/src/test/resources/settings.json b/src/test/resources/settings.json index e2b7382..4271f20 100644 --- a/src/test/resources/settings.json +++ b/src/test/resources/settings.json @@ -12,4 +12,4 @@ "logger": { "language": "en" } -} \ No newline at end of file +} diff --git a/src/test/resources/settings.jsontest.json b/src/test/resources/settings.jsontest.json index bd0c737..6e9a9cd 100644 --- a/src/test/resources/settings.jsontest.json +++ b/src/test/resources/settings.jsontest.json @@ -15,4 +15,4 @@ "arguments": { "start": ["first","second"] } -} \ No newline at end of file +} From 5dd10150f82c5c40d2593d832a38c74a3fac6ca9 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 16:39:01 +0300 Subject: [PATCH 08/38] renamed constants to upper case --- .../core/application/AqualityServices.java | 10 +- src/test/java/tests/logger/LoggerTests.java | 92 +++++++++---------- .../tests/utilities/SettingsFileTests.java | 62 ++++++------- 3 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/main/java/aquality/selenium/core/application/AqualityServices.java b/src/main/java/aquality/selenium/core/application/AqualityServices.java index a9bf69c..f3f6aa0 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityServices.java +++ b/src/main/java/aquality/selenium/core/application/AqualityServices.java @@ -9,7 +9,7 @@ */ public class AqualityServices { - private static final ThreadLocal injectorContainer = new ThreadLocal<>(); + private static final ThreadLocal INJECTOR_CONTAINER = new ThreadLocal<>(); protected AqualityServices() { } @@ -20,11 +20,11 @@ protected AqualityServices() { * @return existing or new injector. */ protected static Injector getInjector() { - if (injectorContainer.get() == null) { + if (INJECTOR_CONTAINER.get() == null) { initInjector(); } - return injectorContainer.get(); + return INJECTOR_CONTAINER.get(); } private static void initInjector() { @@ -38,7 +38,7 @@ private static void initInjector() { * @param is type of custom module. Custom module should be inherited from {@link AqualityModule}. */ protected static void initInjector(T module) { - injectorContainer.remove(); - injectorContainer.set(Guice.createInjector(module)); + INJECTOR_CONTAINER.remove(); + INJECTOR_CONTAINER.set(Guice.createInjector(module)); } } diff --git a/src/test/java/tests/logger/LoggerTests.java b/src/test/java/tests/logger/LoggerTests.java index 8963a42..d69a7ac 100644 --- a/src/test/java/tests/logger/LoggerTests.java +++ b/src/test/java/tests/logger/LoggerTests.java @@ -14,10 +14,10 @@ import static org.testng.Assert.*; public class LoggerTests { - private final static String appenderLogFilePattern = "target/log/appender-%s.log"; - private final static String testMessage = "test message"; - private final static String testExceptionText = "test exception"; - private final static String log4jFieldName = "log4J"; + private final static String APPENDER_LOG_FILE_PATTERN = "target/log/appender-%s.log"; + private final static String TEST_MESSAGE = "test message"; + private final static String TEST_EXCEPTION_TEXT = "test exception"; + private final static String LOG4J_FIELD_NAME = "log4J"; private Logger logger = CustomAqualityServices.getInjector().getInstance(Logger.class); private org.apache.log4j.Logger log4j; private Appender appender; @@ -32,7 +32,7 @@ private void addMessagesAppender() throws IOException { @BeforeGroups("messages") private void initializeLog4jField() throws NoSuchFieldException, IllegalAccessException { - Field log4jField = Logger.class.getDeclaredField(log4jFieldName); + Field log4jField = Logger.class.getDeclaredField(LOG4J_FIELD_NAME); log4jField.setAccessible(true); log4j = ((ThreadLocal) log4jField.get(logger)).get(); } @@ -44,107 +44,107 @@ public void testAqualityServicesShouldReturnInstanceOfLogger() { @Test public void testShouldBePossibleToAddAppender() throws IOException { - logger.addAppender(appender).info(testMessage); + logger.addAppender(appender).info(TEST_MESSAGE); assertTrue(appenderFile.exists(), String.format("New appender should be added to log4j. File '%s' should be created.", appenderFile.getPath())); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } @Test public void testShouldBePossibleToRemoveAppender() throws IOException { - logger.addAppender(appender).removeAppender(appender).info(testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("New appender should be removed from log4j. File '%s' should be empty.", appenderFile.getPath())); + logger.addAppender(appender).removeAppender(appender).info(TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("New appender should be removed from log4j. File '%s' should be empty.", appenderFile.getPath())); } @Test(groups = "messages") public void testInfoMessageShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.FATAL); - logger.info(testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.info(TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); log4j.setLevel(Level.INFO); - logger.info(testMessage); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.info(TEST_MESSAGE); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } @Test(groups = "messages") public void testInfoMessageWithParametersShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.FATAL); - logger.info("%s", testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.info("%s", TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); log4j.setLevel(Level.INFO); - logger.info("%s", testMessage); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.info("%s", TEST_MESSAGE); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } @Test(groups = "messages") public void testDebugMessageWithParametersShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.WARN); - logger.debug("%s", testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.debug("%s", TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); log4j.setLevel(Level.DEBUG); - logger.debug("%s", testMessage); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.debug("%s", TEST_MESSAGE); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } @Test(groups = "messages") public void testDebugMessageShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.WARN); - logger.debug(testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.debug(TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); log4j.setLevel(Level.DEBUG); - logger.debug(testMessage); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.debug(TEST_MESSAGE); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } @Test(groups = "messages") public void testDebugMessageWithThrowableShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.WARN); - logger.debug(testMessage, new Exception(testExceptionText)); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); - assertFalse(isFileContainsText(appenderFile, testExceptionText), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testExceptionText)); + logger.debug(TEST_MESSAGE, new Exception(TEST_EXCEPTION_TEXT)); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); + assertFalse(isFileContainsText(appenderFile, TEST_EXCEPTION_TEXT), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_EXCEPTION_TEXT)); log4j.setLevel(Level.DEBUG); - logger.debug(testMessage, new Exception(testExceptionText)); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); - assertTrue(isFileContainsText(appenderFile, testExceptionText), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testExceptionText)); + logger.debug(TEST_MESSAGE, new Exception(TEST_EXCEPTION_TEXT)); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); + assertTrue(isFileContainsText(appenderFile, TEST_EXCEPTION_TEXT), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_EXCEPTION_TEXT)); } @Test(groups = "messages") public void testWarnMessageShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.ERROR); - logger.warn(testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.warn(TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); log4j.setLevel(Level.WARN); - logger.warn(testMessage); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.warn(TEST_MESSAGE); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } @Test(groups = "messages") public void testFatalMessageShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.OFF); - logger.fatal(testMessage, new Exception(testExceptionText)); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); - assertFalse(isFileContainsText(appenderFile, testExceptionText), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testExceptionText)); + logger.fatal(TEST_MESSAGE, new Exception(TEST_EXCEPTION_TEXT)); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); + assertFalse(isFileContainsText(appenderFile, TEST_EXCEPTION_TEXT), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_EXCEPTION_TEXT)); log4j.setLevel(Level.FATAL); - logger.fatal(testMessage, new Exception(testExceptionText)); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); - assertTrue(isFileContainsText(appenderFile, testExceptionText), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testExceptionText)); + logger.fatal(TEST_MESSAGE, new Exception(TEST_EXCEPTION_TEXT)); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); + assertTrue(isFileContainsText(appenderFile, TEST_EXCEPTION_TEXT), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_EXCEPTION_TEXT)); } @Test(groups = "messages") public void testErrorMessageShouldBeDisplayedAccordingToLogLevel() throws IOException { log4j.setLevel(Level.FATAL); - logger.error(testMessage); - assertFalse(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.error(TEST_MESSAGE); + assertFalse(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' shouldn't contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); log4j.setLevel(Level.ERROR); - logger.error(testMessage); - assertTrue(isFileContainsText(appenderFile, testMessage), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), testMessage)); + logger.error(TEST_MESSAGE); + assertTrue(isFileContainsText(appenderFile, TEST_MESSAGE), String.format("Log '%s' should contain message '%s'.", appenderFile.getPath(), TEST_MESSAGE)); } private Appender getFileAppender(File file) throws IOException { @@ -163,7 +163,7 @@ private boolean isFileContainsText(File file, String line) throws IOException { } private File getRandomAppenderFile() { - return new File(String.format(appenderLogFilePattern, UUID.randomUUID())); + return new File(String.format(APPENDER_LOG_FILE_PATTERN, UUID.randomUUID())); } @AfterMethod diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index 76466ca..242c658 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -15,41 +15,41 @@ import static org.testng.Assert.*; public class SettingsFileTests { - private static final String timeoutPollingIntervalPath = "/timeouts/timeoutPollingInterval"; - private static final String timeoutPollingIntervalKey = "timeouts.timeoutPollingInterval"; - private static final String languageEnvKey = "logger.language"; - private static final String argumentsEnvKey = "arguments.start"; - private static final String profile = "jsontest"; - private static final String profileKey = "profile"; - private static final String fileName = String.format("settings.%s.json", profile); - private static final String defaultFileName = "settings.json"; + private static final String TIMEOUT_POLLING_INTERVAL_PATH = "/timeouts/timeoutPollingInterval"; + private static final String TIMEOUT_POLLING_INTERVAL_KEY = "timeouts.timeoutPollingInterval"; + private static final String LANGUAGE_ENV_KEY = "logger.language"; + private static final String ARGUMENTS_ENV_KEY = "arguments.start"; + private static final String PROFILE = "jsontest"; + private static final String PROFILE_KEY = "PROFILE"; + private static final String FILE_NAME = String.format("settings.%s.json", PROFILE); + private static final String DEFAULT_FILE_NAME = "settings.json"; private ISettingsFile jsonSettingsFile; - private static final Map expectedLanguages = new HashMap() {{ + private static final Map EXPECTED_LANGUAGES = new HashMap() {{ put("language", "ru"); }}; @BeforeMethod public void before() { - System.setProperty(profileKey, profile); + System.setProperty(PROFILE_KEY, PROFILE); jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); } @Test public void testShouldBePossibleToGetDefaultContent() throws IOException { - System.clearProperty(profileKey); + System.clearProperty(PROFILE_KEY); CustomAqualityServices.initInjector(new TestModule()); jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); - String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(defaultFileName).getFile()), Charsets.UTF_8).read().trim(); + String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(DEFAULT_FILE_NAME).getFile()), Charsets.UTF_8).read().trim(); String actualContent = jsonSettingsFile.getContent(); - assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", defaultFileName)); + assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", DEFAULT_FILE_NAME)); } @Test public void testShouldBePossibleToGetContent() throws IOException { - String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(fileName).getFile()), Charsets.UTF_8).read().trim(); + String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(FILE_NAME).getFile()), Charsets.UTF_8).read().trim(); String actualContent = jsonSettingsFile.getContent(); - assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", fileName)); + assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", FILE_NAME)); } @Test @@ -58,12 +58,12 @@ public void testShouldBePossibleToGetValue() { String languageKey = "language"; String language = jsonSettingsFile.getValue(languagePath).toString(); - assertEquals(language, expectedLanguages.get(languageKey), String.format("Logger language in settings file '%s' should be read correctly", fileName)); + assertEquals(language, EXPECTED_LANGUAGES.get(languageKey), String.format("Logger language in settings file '%s' should be read correctly", FILE_NAME)); String newLang = "newLang"; - System.setProperty(languageEnvKey, newLang); + System.setProperty(LANGUAGE_ENV_KEY, newLang); language = jsonSettingsFile.getValue(languagePath).toString(); - assertEquals(language, newLang, String.format("Logger language in settings file '%s' should be overridden with environment variable", fileName)); + assertEquals(language, newLang, String.format("Logger language in settings file '%s' should be overridden with environment variable", FILE_NAME)); } @Test @@ -73,14 +73,14 @@ public void testShouldBePossibleToGetListOfValues() { List arguments = jsonSettingsFile.getList(argumentsPath); assertNotNull(arguments); - assertEquals(arguments, expectedArguments, String.format("List of values in settings file '%s' should be read correctly", fileName)); + assertEquals(arguments, expectedArguments, String.format("List of values in settings file '%s' should be read correctly", FILE_NAME)); expectedArguments = Arrays.asList("firstNew", "secondNew"); String newArgs = "firstNew,secondNew"; - System.setProperty(argumentsEnvKey, newArgs); + System.setProperty(ARGUMENTS_ENV_KEY, newArgs); arguments = jsonSettingsFile.getList(argumentsPath); assertNotNull(arguments); - assertEquals(arguments, expectedArguments, String.format("Value in list in settings file '%s' be overridden with environment variable", fileName)); + assertEquals(arguments, expectedArguments, String.format("Value in list in settings file '%s' be overridden with environment variable", FILE_NAME)); } @Test @@ -89,33 +89,33 @@ public void testShouldBePossibleToGetMap() { Map languages = jsonSettingsFile.getMap(loggerPath); assertNotNull(languages); - assertEquals(languages, expectedLanguages, String.format("Map of values in settings file '%s' should be read correctly", fileName)); + assertEquals(languages, EXPECTED_LANGUAGES, String.format("Map of values in settings file '%s' should be read correctly", FILE_NAME)); String newLanguageValue = "newLangMap"; Map expectedLanguages = new HashMap() {{ put("language", newLanguageValue); }}; - System.setProperty(languageEnvKey, newLanguageValue); + System.setProperty(LANGUAGE_ENV_KEY, newLanguageValue); languages = jsonSettingsFile.getMap(loggerPath); assertNotNull(languages); - assertEquals(languages, expectedLanguages, String.format("Map of values in settings file '%s' should be overridden with environment variable", fileName)); + assertEquals(languages, expectedLanguages, String.format("Map of values in settings file '%s' should be overridden with environment variable", FILE_NAME)); } @Test public void testShouldBePossibleToCheckIsValuePresent() { - boolean isTimeoutsPresent = jsonSettingsFile.isValuePresent(timeoutPollingIntervalPath); - assertTrue(isTimeoutsPresent, String.format("%s value should be present in settings file '%s'", timeoutPollingIntervalPath, fileName)); + boolean isTimeoutsPresent = jsonSettingsFile.isValuePresent(TIMEOUT_POLLING_INTERVAL_PATH); + assertTrue(isTimeoutsPresent, String.format("%s value should be present in settings file '%s'", TIMEOUT_POLLING_INTERVAL_PATH, FILE_NAME)); String wrongPath = "/blabla"; boolean isWrongPathPresent = jsonSettingsFile.isValuePresent(wrongPath); - assertFalse(isWrongPathPresent, String.format("%s value should not be present in settings file '%s'", wrongPath, fileName)); + assertFalse(isWrongPathPresent, String.format("%s value should not be present in settings file '%s'", wrongPath, FILE_NAME)); } @AfterMethod public void after() { - System.clearProperty(profileKey); - System.clearProperty(languageEnvKey); - System.clearProperty(timeoutPollingIntervalKey); - System.clearProperty(argumentsEnvKey); + System.clearProperty(PROFILE_KEY); + System.clearProperty(LANGUAGE_ENV_KEY); + System.clearProperty(TIMEOUT_POLLING_INTERVAL_KEY); + System.clearProperty(ARGUMENTS_ENV_KEY); } } From b7c5b5fb0ce46a4c40ada035f9d6ceec8213a2fb Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 17:08:44 +0300 Subject: [PATCH 09/38] removed redundant method from ISettingsFile --- .../core/utilities/ISettingsFile.java | 7 ----- .../core/utilities/JsonSettingsFile.java | 15 ++-------- .../tests/utilities/SettingsFileTests.java | 28 ++++++------------- 3 files changed, 11 insertions(+), 39 deletions(-) diff --git a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java index 780428d..a67987b 100644 --- a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java +++ b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java @@ -32,13 +32,6 @@ public interface ISettingsFile { */ Map getMap(String path); - /** - * Gets content of settings file. - * - * @return Content of settings file as string. - */ - String getContent(); - /** * Checks if value exists in settings. * diff --git a/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java b/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java index 295200d..5376a77 100644 --- a/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java +++ b/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java @@ -14,18 +14,15 @@ public class JsonSettingsFile implements ISettingsFile { private final ObjectMapper mapper = new ObjectMapper(); - private final String fileCanonicalPath; private final String content; public JsonSettingsFile(File file) throws IOException { this.content = getFileContent(file.getCanonicalPath()); - fileCanonicalPath = file.getCanonicalPath(); } public JsonSettingsFile(String resourceName) { ResourceFile resourceFile = new ResourceFile(resourceName); this.content = resourceFile.getFileContent(); - this.fileCanonicalPath = resourceFile.getFileCanonicalPath(); } @Override @@ -84,10 +81,10 @@ public Map getMap(String jsonPath) { private JsonNode getJsonNode(String jsonPath) { try { - JsonNode node = mapper.readTree(getContent()); + JsonNode node = mapper.readTree(content); return node.at(jsonPath); } catch (IOException e) { - throw new UncheckedIOException(String.format("Json field by json-path %1$s was not found in the file %2$s", jsonPath, getContent()), e); + throw new UncheckedIOException(String.format("Json field by json-path %1$s was not found in the file %2$s", jsonPath, content), e); } } @@ -99,17 +96,9 @@ private String getFileContent(String filename) { } } - public String getContent() { - return content; - } - @Override public boolean isValuePresent(String path) { String value = getValue(path).toString().trim(); return !value.isEmpty(); } - - public String getFileCanonicalPath() { - return fileCanonicalPath; - } } diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index 242c658..3507d8b 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -1,16 +1,15 @@ package tests.utilities; import aquality.selenium.core.utilities.ISettingsFile; -import com.google.common.base.Charsets; -import com.google.common.io.Files; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import tests.application.TestModule; -import java.io.File; -import java.io.IOException; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.testng.Assert.*; @@ -20,9 +19,8 @@ public class SettingsFileTests { private static final String LANGUAGE_ENV_KEY = "logger.language"; private static final String ARGUMENTS_ENV_KEY = "arguments.start"; private static final String PROFILE = "jsontest"; - private static final String PROFILE_KEY = "PROFILE"; + private static final String PROFILE_KEY = "profile"; private static final String FILE_NAME = String.format("settings.%s.json", PROFILE); - private static final String DEFAULT_FILE_NAME = "settings.json"; private ISettingsFile jsonSettingsFile; private static final Map EXPECTED_LANGUAGES = new HashMap() {{ put("language", "ru"); @@ -31,25 +29,17 @@ public class SettingsFileTests { @BeforeMethod public void before() { System.setProperty(PROFILE_KEY, PROFILE); + CustomAqualityServices.initInjector(new TestModule()); jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); } @Test - public void testShouldBePossibleToGetDefaultContent() throws IOException { + public void testShouldBePossibleToGetDefaultContent(){ System.clearProperty(PROFILE_KEY); CustomAqualityServices.initInjector(new TestModule()); jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); - - String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(DEFAULT_FILE_NAME).getFile()), Charsets.UTF_8).read().trim(); - String actualContent = jsonSettingsFile.getContent(); - assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", DEFAULT_FILE_NAME)); - } - - @Test - public void testShouldBePossibleToGetContent() throws IOException { - String expectedContent = Files.asCharSource(new File(getClass().getClassLoader().getResource(FILE_NAME).getFile()), Charsets.UTF_8).read().trim(); - String actualContent = jsonSettingsFile.getContent(); - assertEquals(actualContent, expectedContent, String.format("Settings file %s should be read correctly", FILE_NAME)); + String language = jsonSettingsFile.getValue("/logger/language").toString(); + assertEquals(language, "en", "Logger language in default settings file should be read correctly"); } @Test From 890314e1cf589fa89731e5ff63c1a8991d6145d5 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 18:41:34 +0300 Subject: [PATCH 10/38] fixed naming and added empty line at the end of files --- .../tests/configurations/EnvConfigurationTests.java | 9 +++++---- .../configurations/LoggerConfigurationTests.java | 2 +- .../configurations/ProfileConfigurationTests.java | 13 ++++++------- src/test/resources/settings.custom.json | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index e4fd60f..4e992bf 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -12,11 +12,11 @@ public class EnvConfigurationTests { - private static final String languageKey = "logger.language"; + private static final String LANGUAGE_KEY = "logger.language"; @BeforeMethod public void before(){ - System.setProperty(languageKey, "ru"); + System.setProperty(LANGUAGE_KEY, "ru"); CustomAqualityServices.initInjector(new TestModule()); } @@ -28,6 +28,7 @@ public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { @AfterMethod public void after(){ - System.clearProperty(languageKey); + System.clearProperty(LANGUAGE_KEY); + CustomAqualityServices.initInjector(new TestModule()); } -} \ No newline at end of file +} diff --git a/src/test/java/tests/configurations/LoggerConfigurationTests.java b/src/test/java/tests/configurations/LoggerConfigurationTests.java index 1263d91..19c7985 100644 --- a/src/test/java/tests/configurations/LoggerConfigurationTests.java +++ b/src/test/java/tests/configurations/LoggerConfigurationTests.java @@ -13,4 +13,4 @@ public void testShouldBePossibleToGetLanguage() { SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); assertEquals(language, SupportedLanguage.EN, "Current language should be got from logger configuration"); } -} \ No newline at end of file +} diff --git a/src/test/java/tests/configurations/ProfileConfigurationTests.java b/src/test/java/tests/configurations/ProfileConfigurationTests.java index f8b32b8..27b66b8 100644 --- a/src/test/java/tests/configurations/ProfileConfigurationTests.java +++ b/src/test/java/tests/configurations/ProfileConfigurationTests.java @@ -6,28 +6,27 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; -import tests.application.TestModule; import static org.testng.Assert.assertEquals; public class ProfileConfigurationTests { - private static final String profileKey = "profile"; - private static final String profile = "custom"; + private static final String PROFILE_KEY = "profile"; + private static final String PROFILE = "custom"; @BeforeMethod public void before(){ - System.setProperty(profileKey, profile); + System.setProperty(PROFILE_KEY, PROFILE); } @Test public void testShouldBePossibleToGetLanguageFromNewSettingsFile() { SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); - assertEquals(language, SupportedLanguage.RU, String.format("Current language should be got from %s profile", profile)); + assertEquals(language, SupportedLanguage.RU, String.format("Current language should be got from %s profile", PROFILE)); } @AfterMethod public void after(){ - System.clearProperty(profileKey); + System.clearProperty(PROFILE_KEY); } -} \ No newline at end of file +} diff --git a/src/test/resources/settings.custom.json b/src/test/resources/settings.custom.json index 7a40015..bb53339 100644 --- a/src/test/resources/settings.custom.json +++ b/src/test/resources/settings.custom.json @@ -12,4 +12,4 @@ "logger": { "language": "ru" } -} \ No newline at end of file +} From 5ad251975c2d86040ec12247aee52ee85aa4e31b Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 18:44:58 +0300 Subject: [PATCH 11/38] fixed naming and added empty line at the end of files --- .../configurations/EnvConfigurationTests.java | 20 +++++++------------ .../TimeoutConfigurationTests.java | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 6d81c3e..3b90e4e 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -17,18 +17,15 @@ public class EnvConfigurationTests { private static final String LANGUAGE_KEY = "logger.language"; - private static final String languageKey = "logger.language"; - private static final String languageValue = "ru"; - private static final String conditionTimeoutKey = "timeouts.timeoutCondition"; - private static final String newTimeoutValue = "10000"; + private static final String LANGUAGE_VALUE = "ru"; + private static final String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; + private static final String NEW_TIMEOUT_VALUE = "10000"; private Injector injector; @BeforeMethod public void before(){ System.setProperty(LANGUAGE_KEY, "ru"); - public void before() { - System.setProperty(languageKey, languageValue); - System.setProperty(conditionTimeoutKey, newTimeoutValue); + System.setProperty(CONDITION_TIMEOUT_KEY, NEW_TIMEOUT_VALUE); CustomAqualityServices.initInjector(new TestModule()); injector = CustomAqualityServices.getInjector(); } @@ -42,12 +39,12 @@ public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { @Test public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { long conditionTimeout = injector.getInstance(ITimeoutConfiguration.class).getCondition(); - assertEquals(conditionTimeout, Long.parseLong(newTimeoutValue), "Condition timeout should be overridden with env variable"); + assertEquals(conditionTimeout, Long.parseLong(NEW_TIMEOUT_VALUE), "Condition timeout should be overridden with env variable"); } @Test public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { - System.setProperty(conditionTimeoutKey, languageValue); + System.setProperty(CONDITION_TIMEOUT_KEY, LANGUAGE_VALUE); try { CustomAqualityServices.initInjector(new TestModule()); CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class).getCommand(); @@ -60,10 +57,7 @@ public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { @AfterMethod public void after(){ System.clearProperty(LANGUAGE_KEY); + System.clearProperty(CONDITION_TIMEOUT_KEY); CustomAqualityServices.initInjector(new TestModule()); - public void after() { - System.clearProperty(languageKey); - System.clearProperty(conditionTimeoutKey); - CustomAqualityServices.initInjector(new AqualityModule()); } } diff --git a/src/test/java/tests/configurations/TimeoutConfigurationTests.java b/src/test/java/tests/configurations/TimeoutConfigurationTests.java index e49966f..456f932 100644 --- a/src/test/java/tests/configurations/TimeoutConfigurationTests.java +++ b/src/test/java/tests/configurations/TimeoutConfigurationTests.java @@ -16,4 +16,4 @@ public void testShouldBePossibleToGetTimeoutConfiguration() { assertEquals(timeoutConfiguration.getImplicit(), 0, "Implicit timeout should be got"); assertEquals(timeoutConfiguration.getPollingInterval(), 300, "Polling interval should be got"); } -} \ No newline at end of file +} From b2f48c854cfc0168f6e18d294255078f590f8a03 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 28 Jan 2020 18:56:17 +0300 Subject: [PATCH 12/38] fixed naming and added empty line at the end of files --- .../configurations/EnvConfigurationTests.java | 35 ++++++------------- .../RetryConfigurationTests.java | 2 +- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 23068a8..4460e1a 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -18,24 +18,17 @@ public class EnvConfigurationTests { private static final String LANGUAGE_KEY = "logger.language"; - private static final String LANGUAGE_VALUE = "ru"; + private static final String NEW_STRING_VALUE = "ru"; private static final String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; - private static final String NEW_TIMEOUT_VALUE = "10000"; - private static final String languageKey = "logger.language"; - private static final String newStringValue = "ru"; - private static final String conditionTimeoutKey = "timeouts.timeoutCondition"; - private static final String retryNumberKey = "retry.number"; - private static final String newIntValue = "10000"; + private static final String NEW_INT_VALUE = "10000"; + private static final String RETRY_NUMBER_KEY = "retry.number"; private Injector injector; @BeforeMethod public void before() { - System.setProperty(languageKey, newStringValue); - System.setProperty(conditionTimeoutKey, newIntValue); - System.setProperty(retryNumberKey, newIntValue); - public void before(){ - System.setProperty(LANGUAGE_KEY, "ru"); - System.setProperty(CONDITION_TIMEOUT_KEY, NEW_TIMEOUT_VALUE); + System.setProperty(LANGUAGE_KEY, NEW_STRING_VALUE); + System.setProperty(CONDITION_TIMEOUT_KEY, NEW_INT_VALUE); + System.setProperty(RETRY_NUMBER_KEY, NEW_INT_VALUE); CustomAqualityServices.initInjector(new TestModule()); injector = CustomAqualityServices.getInjector(); } @@ -49,20 +42,18 @@ public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { @Test public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { long conditionTimeout = injector.getInstance(ITimeoutConfiguration.class).getCondition(); - assertEquals(conditionTimeout, Long.parseLong(newIntValue), "Condition timeout should be overridden with env variable"); + assertEquals(conditionTimeout, Long.parseLong(NEW_INT_VALUE), "Condition timeout should be overridden with env variable"); } @Test public void testShouldBePossibleToOverrideRetryConfigurationWithEnvVariable() { int retryNumber = injector.getInstance(IRetryConfiguration.class).getNumber(); - assertEquals(retryNumber, Long.parseLong(newIntValue), "Number of retry attempts should be overridden with env variable"); - assertEquals(conditionTimeout, Long.parseLong(NEW_TIMEOUT_VALUE), "Condition timeout should be overridden with env variable"); + assertEquals(retryNumber, Long.parseLong(NEW_INT_VALUE), "Number of retry attempts should be overridden with env variable"); } @Test public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { - System.setProperty(CONDITION_TIMEOUT_KEY, LANGUAGE_VALUE); - System.setProperty(conditionTimeoutKey, newStringValue); + System.setProperty(CONDITION_TIMEOUT_KEY, NEW_STRING_VALUE); try { CustomAqualityServices.initInjector(new TestModule()); CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class).getCommand(); @@ -74,7 +65,7 @@ public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { @Test public void testNumberFormatExceptionShouldBeThrownIfRetryConfigurationIsNotANumber() { - System.setProperty(retryNumberKey, newStringValue); + System.setProperty(RETRY_NUMBER_KEY, NEW_STRING_VALUE); try { CustomAqualityServices.initInjector(new TestModule()); CustomAqualityServices.getInjector().getInstance(IRetryConfiguration.class).getNumber(); @@ -88,11 +79,7 @@ public void testNumberFormatExceptionShouldBeThrownIfRetryConfigurationIsNotANum public void after(){ System.clearProperty(LANGUAGE_KEY); System.clearProperty(CONDITION_TIMEOUT_KEY); + System.clearProperty(RETRY_NUMBER_KEY); CustomAqualityServices.initInjector(new TestModule()); - public void after() { - System.clearProperty(languageKey); - System.clearProperty(conditionTimeoutKey); - System.clearProperty(retryNumberKey); - CustomAqualityServices.initInjector(new AqualityModule()); } } diff --git a/src/test/java/tests/configurations/RetryConfigurationTests.java b/src/test/java/tests/configurations/RetryConfigurationTests.java index 1104e8a..42cbffc 100644 --- a/src/test/java/tests/configurations/RetryConfigurationTests.java +++ b/src/test/java/tests/configurations/RetryConfigurationTests.java @@ -15,4 +15,4 @@ public void testShouldBePossibleToGetRetryConfiguration() { assertEquals(retryConfiguration.getNumber(), 2, "Number of retry attempts timeout should be got"); assertEquals(retryConfiguration.getPollingInterval(), 300, "Polling interval of retrier should be got"); } -} \ No newline at end of file +} From 4619ac0213a0c14b2fba8528948b4cbbe1c2c24f Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Wed, 29 Jan 2020 17:31:00 +0300 Subject: [PATCH 13/38] merged with master and added test for CustomSettingsFile --- .../core/application/AqualityModule.java | 6 +- .../utilities/CustomSettingsFileTests.java | 58 +++++++++++++++++++ .../tests/utilities/SettingsFileTests.java | 12 ++-- src/test/resources/TestSuite.xml | 1 + 4 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/test/java/tests/utilities/CustomSettingsFileTests.java diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 096dfd3..91a5e18 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,12 +1,10 @@ package aquality.selenium.core.application; +import aquality.selenium.core.logging.Logger; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; import com.google.inject.AbstractModule; -import aquality.selenium.core.logging.Logger; -import com.google.inject.AbstractModule; import com.google.inject.Provider; -import com.google.inject.Provides; /** * Describes all dependencies which is registered for the project. @@ -25,6 +23,7 @@ public AqualityModule (Provider applicationProvider) { @Override protected void configure() { bind(IApplication.class).toProvider(applicationProvider); + bind(ISettingsFile.class).toInstance(getSettings()); bind(Logger.class).toInstance(Logger.getInstance()); } @@ -36,7 +35,6 @@ protected void configure() { * * @return An instance of settings. */ - @Provides protected ISettingsFile getSettings() { String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json"; return new JsonSettingsFile(settingsProfile); diff --git a/src/test/java/tests/utilities/CustomSettingsFileTests.java b/src/test/java/tests/utilities/CustomSettingsFileTests.java new file mode 100644 index 0000000..67d9ba9 --- /dev/null +++ b/src/test/java/tests/utilities/CustomSettingsFileTests.java @@ -0,0 +1,58 @@ +package tests.utilities; + +import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Provider; +import org.testng.Assert; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import tests.application.browser.ChromeApplication; + +import java.util.List; +import java.util.Map; + +public class CustomSettingsFileTests { + + @Test + public void testShouldBePossibleToOverrideSettingsFile() { + CustomAqualityServices.initInjector(new CustomModule(CustomAqualityServices::getApplication)); + ISettingsFile jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); + Object value = jsonSettingsFile.getValue("/timeouts/timeoutPollingInterval"); + Assert.assertNull(value, "Value should be got from CustomSettingsFile"); + } + + private class CustomModule extends AqualityModule { + + CustomModule(Provider applicationProvider) { + super(applicationProvider); + } + + @Override + protected ISettingsFile getSettings() { + return new CustomSettingsFile(); + } + } + + private class CustomSettingsFile implements ISettingsFile { + + @Override + public Object getValue(String path) { + return null; + } + + @Override + public List getList(String path) { + return null; + } + + @Override + public Map getMap(String path) { + return null; + } + + @Override + public boolean isValuePresent(String path) { + return false; + } + } +} diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index 3507d8b..4c14048 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -29,15 +29,15 @@ public class SettingsFileTests { @BeforeMethod public void before() { System.setProperty(PROFILE_KEY, PROFILE); - CustomAqualityServices.initInjector(new TestModule()); - jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); + CustomAqualityServices.initInjector(getTestModule()); + jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); } @Test public void testShouldBePossibleToGetDefaultContent(){ System.clearProperty(PROFILE_KEY); - CustomAqualityServices.initInjector(new TestModule()); - jsonSettingsFile = CustomAqualityServices.getInjector().getInstance(ISettingsFile.class); + CustomAqualityServices.initInjector(getTestModule()); + jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); String language = jsonSettingsFile.getValue("/logger/language").toString(); assertEquals(language, "en", "Logger language in default settings file should be read correctly"); } @@ -108,4 +108,8 @@ public void after() { System.clearProperty(TIMEOUT_POLLING_INTERVAL_KEY); System.clearProperty(ARGUMENTS_ENV_KEY); } + + private TestModule getTestModule(){ + return new TestModule(CustomAqualityServices::getApplication); + } } diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index b9b03ec..06edb02 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -5,6 +5,7 @@ + From ccac733c86e0f8f1fddf22c0346b3894acd3a1b0 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Wed, 29 Jan 2020 17:45:26 +0300 Subject: [PATCH 14/38] fix for the tests --- .../java/tests/utilities/SettingsFileTests.java | 14 +++++++++++--- src/test/resources/settings.local.json | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/settings.local.json diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index 4c14048..bb285fe 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -6,6 +6,7 @@ import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import tests.application.TestModule; + import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -22,19 +23,21 @@ public class SettingsFileTests { private static final String PROFILE_KEY = "profile"; private static final String FILE_NAME = String.format("settings.%s.json", PROFILE); private ISettingsFile jsonSettingsFile; + private String previousProfile; private static final Map EXPECTED_LANGUAGES = new HashMap() {{ put("language", "ru"); }}; @BeforeMethod public void before() { + previousProfile = System.getProperty(PROFILE_KEY); System.setProperty(PROFILE_KEY, PROFILE); CustomAqualityServices.initInjector(getTestModule()); jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); } @Test - public void testShouldBePossibleToGetDefaultContent(){ + public void testShouldBePossibleToGetDefaultContent() { System.clearProperty(PROFILE_KEY); CustomAqualityServices.initInjector(getTestModule()); jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); @@ -103,13 +106,18 @@ public void testShouldBePossibleToCheckIsValuePresent() { @AfterMethod public void after() { - System.clearProperty(PROFILE_KEY); + if (previousProfile == null) { + System.clearProperty(PROFILE_KEY); + } else { + System.setProperty(PROFILE_KEY, previousProfile); + } + System.clearProperty(LANGUAGE_ENV_KEY); System.clearProperty(TIMEOUT_POLLING_INTERVAL_KEY); System.clearProperty(ARGUMENTS_ENV_KEY); } - private TestModule getTestModule(){ + private TestModule getTestModule() { return new TestModule(CustomAqualityServices::getApplication); } } diff --git a/src/test/resources/settings.local.json b/src/test/resources/settings.local.json new file mode 100644 index 0000000..4271f20 --- /dev/null +++ b/src/test/resources/settings.local.json @@ -0,0 +1,15 @@ +{ + "timeouts": { + "timeoutImplicit": 0, + "timeoutCondition": 30, + "timeoutPollingInterval": 300, + "timeoutCommand": 60 + }, + "retry": { + "number": 2, + "pollingInterval": 300 + }, + "logger": { + "language": "en" + } +} From d58605f4c573a6f5f95ca6e4a4811eaf982f2e01 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Wed, 29 Jan 2020 18:17:07 +0300 Subject: [PATCH 15/38] merge and small refactoring of tests --- .../tests/configurations/BaseProfileTest.java | 24 +++++++++++++++++++ .../configurations/EnvConfigurationTests.java | 11 ++++++--- .../LoggerConfigurationTests.java | 2 +- .../ProfileConfigurationTests.java | 16 +++++-------- .../tests/utilities/SettingsFileTests.java | 14 ++++------- 5 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 src/test/java/tests/configurations/BaseProfileTest.java diff --git a/src/test/java/tests/configurations/BaseProfileTest.java b/src/test/java/tests/configurations/BaseProfileTest.java new file mode 100644 index 0000000..f276ec5 --- /dev/null +++ b/src/test/java/tests/configurations/BaseProfileTest.java @@ -0,0 +1,24 @@ +package tests.configurations; + +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; + +public class BaseProfileTest { + + protected static final String PROFILE_KEY = "profile"; + private String previousProfile; + + @BeforeMethod + public void before() { + previousProfile = System.getProperty(PROFILE_KEY); + } + + @AfterMethod + public void after() { + if (previousProfile == null) { + System.clearProperty(PROFILE_KEY); + } else { + System.setProperty(PROFILE_KEY, previousProfile); + } + } +} diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 4e992bf..be82a60 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -1,5 +1,6 @@ package tests.configurations; +import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.localization.SupportedLanguage; import org.testng.annotations.AfterMethod; @@ -17,18 +18,22 @@ public class EnvConfigurationTests { @BeforeMethod public void before(){ System.setProperty(LANGUAGE_KEY, "ru"); - CustomAqualityServices.initInjector(new TestModule()); + initInjector(); } @Test public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { - SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); + SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); assertEquals(language, SupportedLanguage.RU, "Current language should be overridden with env variable"); } @AfterMethod public void after(){ System.clearProperty(LANGUAGE_KEY); - CustomAqualityServices.initInjector(new TestModule()); + initInjector(); + } + + private void initInjector(){ + CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); } } diff --git a/src/test/java/tests/configurations/LoggerConfigurationTests.java b/src/test/java/tests/configurations/LoggerConfigurationTests.java index 19c7985..f6caa67 100644 --- a/src/test/java/tests/configurations/LoggerConfigurationTests.java +++ b/src/test/java/tests/configurations/LoggerConfigurationTests.java @@ -10,7 +10,7 @@ public class LoggerConfigurationTests { @Test public void testShouldBePossibleToGetLanguage() { - SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); + SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); assertEquals(language, SupportedLanguage.EN, "Current language should be got from logger configuration"); } } diff --git a/src/test/java/tests/configurations/ProfileConfigurationTests.java b/src/test/java/tests/configurations/ProfileConfigurationTests.java index 27b66b8..f0a3746 100644 --- a/src/test/java/tests/configurations/ProfileConfigurationTests.java +++ b/src/test/java/tests/configurations/ProfileConfigurationTests.java @@ -1,32 +1,28 @@ package tests.configurations; +import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.localization.SupportedLanguage; -import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import static org.testng.Assert.assertEquals; -public class ProfileConfigurationTests { +public class ProfileConfigurationTests extends BaseProfileTest { - private static final String PROFILE_KEY = "profile"; private static final String PROFILE = "custom"; @BeforeMethod - public void before(){ + public void before() { System.setProperty(PROFILE_KEY, PROFILE); + CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); } @Test public void testShouldBePossibleToGetLanguageFromNewSettingsFile() { - SupportedLanguage language = CustomAqualityServices.getInjector().getInstance(ILoggerConfiguration.class).getLanguage(); - assertEquals(language, SupportedLanguage.RU, String.format("Current language should be got from %s profile", PROFILE)); - } - @AfterMethod - public void after(){ - System.clearProperty(PROFILE_KEY); + SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, SupportedLanguage.RU, String.format("Current language should be got from %s profile", PROFILE)); } } diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index bb285fe..f1fcef0 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -1,11 +1,13 @@ package tests.utilities; +import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.utilities.ISettingsFile; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import tests.application.TestModule; +import tests.configurations.BaseProfileTest; import java.util.Arrays; import java.util.HashMap; @@ -14,23 +16,20 @@ import static org.testng.Assert.*; -public class SettingsFileTests { +public class SettingsFileTests extends BaseProfileTest { private static final String TIMEOUT_POLLING_INTERVAL_PATH = "/timeouts/timeoutPollingInterval"; private static final String TIMEOUT_POLLING_INTERVAL_KEY = "timeouts.timeoutPollingInterval"; private static final String LANGUAGE_ENV_KEY = "logger.language"; private static final String ARGUMENTS_ENV_KEY = "arguments.start"; private static final String PROFILE = "jsontest"; - private static final String PROFILE_KEY = "profile"; private static final String FILE_NAME = String.format("settings.%s.json", PROFILE); private ISettingsFile jsonSettingsFile; - private String previousProfile; private static final Map EXPECTED_LANGUAGES = new HashMap() {{ put("language", "ru"); }}; @BeforeMethod public void before() { - previousProfile = System.getProperty(PROFILE_KEY); System.setProperty(PROFILE_KEY, PROFILE); CustomAqualityServices.initInjector(getTestModule()); jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); @@ -106,15 +105,10 @@ public void testShouldBePossibleToCheckIsValuePresent() { @AfterMethod public void after() { - if (previousProfile == null) { - System.clearProperty(PROFILE_KEY); - } else { - System.setProperty(PROFILE_KEY, previousProfile); - } - System.clearProperty(LANGUAGE_ENV_KEY); System.clearProperty(TIMEOUT_POLLING_INTERVAL_KEY); System.clearProperty(ARGUMENTS_ENV_KEY); + CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); } private TestModule getTestModule() { From 7513559e0cc16db095fcc7ed54346bf46a2465d7 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Wed, 29 Jan 2020 18:23:04 +0300 Subject: [PATCH 16/38] merge from master --- .../configurations/EnvConfigurationTests.java | 22 +++++-------------- .../TimeoutConfigurationTests.java | 2 +- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 39b087e..883a225 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -4,7 +4,6 @@ import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.configurations.ITimeoutConfiguration; import aquality.selenium.core.localization.SupportedLanguage; -import com.google.inject.Injector; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -20,27 +19,23 @@ public class EnvConfigurationTests { private static final String LANGUAGE_VALUE = "ru"; private static final String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; private static final String NEW_TIMEOUT_VALUE = "10000"; - private Injector injector; @BeforeMethod public void before(){ - System.setProperty(LANGUAGE_KEY, "ru"); + System.setProperty(LANGUAGE_KEY, LANGUAGE_VALUE); System.setProperty(CONDITION_TIMEOUT_KEY, NEW_TIMEOUT_VALUE); - CustomAqualityServices.initInjector(new TestModule()); - injector = CustomAqualityServices.getInjector(); - initInjector(); + CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); } @Test public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); - SupportedLanguage language = injector.getInstance(ILoggerConfiguration.class).getLanguage(); assertEquals(language, SupportedLanguage.RU, "Current language should be overridden with env variable"); } @Test public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { - long conditionTimeout = injector.getInstance(ITimeoutConfiguration.class).getCondition(); + long conditionTimeout = CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class).getCondition(); assertEquals(conditionTimeout, Long.parseLong(NEW_TIMEOUT_VALUE), "Condition timeout should be overridden with env variable"); } @@ -48,8 +43,8 @@ public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { System.setProperty(CONDITION_TIMEOUT_KEY, LANGUAGE_VALUE); try { - CustomAqualityServices.initInjector(new TestModule()); - CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class).getCommand(); + CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); + CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class).getCommand(); } catch (Exception e) { Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); Assert.assertTrue(e.getMessage().contains("NumberFormatException")); @@ -59,12 +54,7 @@ public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { @AfterMethod public void after(){ System.clearProperty(LANGUAGE_KEY); - initInjector(); - } - - private void initInjector(){ - CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); System.clearProperty(CONDITION_TIMEOUT_KEY); - CustomAqualityServices.initInjector(new TestModule()); + CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); } } diff --git a/src/test/java/tests/configurations/TimeoutConfigurationTests.java b/src/test/java/tests/configurations/TimeoutConfigurationTests.java index 456f932..9b2f84a 100644 --- a/src/test/java/tests/configurations/TimeoutConfigurationTests.java +++ b/src/test/java/tests/configurations/TimeoutConfigurationTests.java @@ -10,7 +10,7 @@ public class TimeoutConfigurationTests { @Test public void testShouldBePossibleToGetTimeoutConfiguration() { - ITimeoutConfiguration timeoutConfiguration = CustomAqualityServices.getInjector().getInstance(ITimeoutConfiguration.class); + ITimeoutConfiguration timeoutConfiguration = CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class); assertEquals(timeoutConfiguration.getCommand(), 60, "Command timeout should be got"); assertEquals(timeoutConfiguration.getCondition(), 30, "Condition timeout should be got"); assertEquals(timeoutConfiguration.getImplicit(), 0, "Implicit timeout should be got"); From a968e5c9b30ab949734022c2e6d2bd3f5717c83f Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Wed, 29 Jan 2020 18:43:14 +0300 Subject: [PATCH 17/38] merge from master --- .../core/application/AqualityModule.java | 4 -- .../configurations/EnvConfigurationTests.java | 41 +++++++------------ .../RetryConfigurationTests.java | 2 +- .../utilities/CustomSettingsFileTests.java | 6 +++ 4 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 8673821..2d41fe9 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,10 +1,6 @@ package aquality.selenium.core.application; import aquality.selenium.core.logging.Logger; -import aquality.selenium.core.configurations.ILoggerConfiguration; -import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.configurations.LoggerConfiguration; -import aquality.selenium.core.configurations.TimeoutConfiguration; import aquality.selenium.core.configurations.*; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 518f7f4..7fbcc75 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -11,10 +11,9 @@ import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import tests.application.TestModule; - import static org.testng.Assert.assertEquals; -public class EnvConfigurationTests { +public class EnvConfigurationTests extends BaseProfileTest{ private static final String LANGUAGE_KEY = "logger.language"; private static final String NEW_STRING_VALUE = "ru"; @@ -27,11 +26,6 @@ public void before() { System.setProperty(LANGUAGE_KEY, NEW_STRING_VALUE); System.setProperty(CONDITION_TIMEOUT_KEY, NEW_INT_VALUE); System.setProperty(RETRY_NUMBER_KEY, NEW_INT_VALUE); - CustomAqualityServices.initInjector(new TestModule()); - injector = CustomAqualityServices.getInjector(); - public void before(){ - System.setProperty(LANGUAGE_KEY, LANGUAGE_VALUE); - System.setProperty(CONDITION_TIMEOUT_KEY, NEW_TIMEOUT_VALUE); CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); } @@ -44,47 +38,42 @@ public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { @Test public void testShouldBePossibleToOverrideTimeoutWithEnvVariable() { long conditionTimeout = CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class).getCondition(); - assertEquals(conditionTimeout, Long.parseLong(NEW_TIMEOUT_VALUE), "Condition timeout should be overridden with env variable"); - long conditionTimeout = injector.getInstance(ITimeoutConfiguration.class).getCondition(); assertEquals(conditionTimeout, Long.parseLong(NEW_INT_VALUE), "Condition timeout should be overridden with env variable"); } @Test public void testShouldBePossibleToOverrideRetryConfigurationWithEnvVariable() { - int retryNumber = injector.getInstance(IRetryConfiguration.class).getNumber(); + int retryNumber = CustomAqualityServices.getServiceProvider().getInstance(IRetryConfiguration.class).getNumber(); assertEquals(retryNumber, Long.parseLong(NEW_INT_VALUE), "Number of retry attempts should be overridden with env variable"); } @Test public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { System.setProperty(CONDITION_TIMEOUT_KEY, NEW_STRING_VALUE); - try { - CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); - CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class).getCommand(); - } catch (Exception e) { - Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); - Assert.assertTrue(e.getMessage().contains("NumberFormatException")); - } + checkNumberFormatException(() -> CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class).getCommand()); } @Test public void testNumberFormatExceptionShouldBeThrownIfRetryConfigurationIsNotANumber() { System.setProperty(RETRY_NUMBER_KEY, NEW_STRING_VALUE); - try { - CustomAqualityServices.initInjector(new TestModule()); - CustomAqualityServices.getInjector().getInstance(IRetryConfiguration.class).getNumber(); - } catch (Exception e) { - Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); - Assert.assertTrue(e.getMessage().contains("NumberFormatException")); - } + checkNumberFormatException(() -> CustomAqualityServices.getServiceProvider().getInstance(IRetryConfiguration.class).getNumber()); } @AfterMethod public void after(){ System.clearProperty(LANGUAGE_KEY); System.clearProperty(CONDITION_TIMEOUT_KEY); - CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); System.clearProperty(RETRY_NUMBER_KEY); - CustomAqualityServices.initInjector(new TestModule()); + CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); + } + + private void checkNumberFormatException(Runnable getNumberAction){ + try { + CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); + getNumberAction.run(); + } catch (Exception e) { + Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); + Assert.assertTrue(e.getMessage().contains("NumberFormatException")); + } } } diff --git a/src/test/java/tests/configurations/RetryConfigurationTests.java b/src/test/java/tests/configurations/RetryConfigurationTests.java index 42cbffc..4e05212 100644 --- a/src/test/java/tests/configurations/RetryConfigurationTests.java +++ b/src/test/java/tests/configurations/RetryConfigurationTests.java @@ -11,7 +11,7 @@ public class RetryConfigurationTests { @Test public void testShouldBePossibleToGetRetryConfiguration() { - IRetryConfiguration retryConfiguration = CustomAqualityServices.getInjector().getInstance(IRetryConfiguration.class); + IRetryConfiguration retryConfiguration = CustomAqualityServices.getServiceProvider().getInstance(IRetryConfiguration.class); assertEquals(retryConfiguration.getNumber(), 2, "Number of retry attempts timeout should be got"); assertEquals(retryConfiguration.getPollingInterval(), 300, "Polling interval of retrier should be got"); } diff --git a/src/test/java/tests/utilities/CustomSettingsFileTests.java b/src/test/java/tests/utilities/CustomSettingsFileTests.java index 67d9ba9..69b0c23 100644 --- a/src/test/java/tests/utilities/CustomSettingsFileTests.java +++ b/src/test/java/tests/utilities/CustomSettingsFileTests.java @@ -4,6 +4,7 @@ import aquality.selenium.core.utilities.ISettingsFile; import com.google.inject.Provider; import org.testng.Assert; +import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import tests.application.browser.ChromeApplication; @@ -21,6 +22,11 @@ public void testShouldBePossibleToOverrideSettingsFile() { Assert.assertNull(value, "Value should be got from CustomSettingsFile"); } + @AfterMethod + public void after(){ + CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); + } + private class CustomModule extends AqualityModule { CustomModule(Provider applicationProvider) { From 792cda2035bfe1ba09b2d6fd98ee9d936579a30f Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 10:20:54 +0300 Subject: [PATCH 18/38] extracted IElementCacheConfiguration --- .../core/application/AqualityModule.java | 1 + .../ElementCacheConfiguration.java | 20 +++++++++++++++++++ .../IElementCacheConfiguration.java | 12 +++++++++++ src/main/resources/settings.json | 16 +++++++++++++++ .../ElementCacheConfigurationTests.java | 16 +++++++++++++++ .../configurations/EnvConfigurationTests.java | 19 +++++++++++++++--- src/test/resources/TestSuite.xml | 1 + src/test/resources/settings.custom.json | 3 +++ src/test/resources/settings.json | 3 +++ src/test/resources/settings.local.json | 3 +++ 10 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java create mode 100644 src/main/java/aquality/selenium/core/configurations/IElementCacheConfiguration.java create mode 100644 src/test/java/tests/configurations/ElementCacheConfigurationTests.java diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 2d41fe9..96afc1b 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -29,6 +29,7 @@ protected void configure() { bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); bind(IRetryConfiguration.class).to(RetryConfiguration.class); + bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class); } /** diff --git a/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java b/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java new file mode 100644 index 0000000..959ff7b --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java @@ -0,0 +1,20 @@ +package aquality.selenium.core.configurations; + +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; + +public class ElementCacheConfiguration implements IElementCacheConfiguration{ + + private static final String JSON_PATH = "/elementCache/isEnabled"; + private boolean isEnabled; + + @Inject + public ElementCacheConfiguration(ISettingsFile settingsFile){ + isEnabled = settingsFile.isValuePresent(JSON_PATH) && Boolean.valueOf(settingsFile.getValue(JSON_PATH).toString()); + } + + @Override + public boolean isEnabled() { + return isEnabled; + } +} diff --git a/src/main/java/aquality/selenium/core/configurations/IElementCacheConfiguration.java b/src/main/java/aquality/selenium/core/configurations/IElementCacheConfiguration.java new file mode 100644 index 0000000..93c16f4 --- /dev/null +++ b/src/main/java/aquality/selenium/core/configurations/IElementCacheConfiguration.java @@ -0,0 +1,12 @@ +package aquality.selenium.core.configurations; + +/** + * Provides element's cache configuration. + */ +public interface IElementCacheConfiguration { + + /** + * @return Is element caching allowed or not. + */ + boolean isEnabled(); +} diff --git a/src/main/resources/settings.json b/src/main/resources/settings.json index 2c63c08..cc2e51d 100644 --- a/src/main/resources/settings.json +++ b/src/main/resources/settings.json @@ -1,2 +1,18 @@ { + "timeouts": { + "timeoutImplicit": 0, + "timeoutCondition": 30, + "timeoutPollingInterval": 300, + "timeoutCommand": 60 + }, + "retry": { + "number": 2, + "pollingInterval": 300 + }, + "logger": { + "language": "en" + }, + "elementCache": { + "isEnabled": false + } } diff --git a/src/test/java/tests/configurations/ElementCacheConfigurationTests.java b/src/test/java/tests/configurations/ElementCacheConfigurationTests.java new file mode 100644 index 0000000..f5735bd --- /dev/null +++ b/src/test/java/tests/configurations/ElementCacheConfigurationTests.java @@ -0,0 +1,16 @@ +package tests.configurations; + +import aquality.selenium.core.configurations.IElementCacheConfiguration; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; + +import static org.testng.Assert.assertFalse; + +public class ElementCacheConfigurationTests { + + @Test + public void testShouldBePossibleCheckIsEnableElementCache() { + boolean isEnable = CustomAqualityServices.getServiceProvider().getInstance(IElementCacheConfiguration.class).isEnabled(); + assertFalse(isEnable, "Element cache is disabled by default"); + } +} diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 7fbcc75..293ea64 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -1,6 +1,7 @@ package tests.configurations; import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.configurations.IElementCacheConfiguration; import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.configurations.IRetryConfiguration; import aquality.selenium.core.configurations.ITimeoutConfiguration; @@ -11,11 +12,15 @@ import org.testng.annotations.Test; import tests.application.CustomAqualityServices; import tests.application.TestModule; + import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; -public class EnvConfigurationTests extends BaseProfileTest{ +public class EnvConfigurationTests extends BaseProfileTest { private static final String LANGUAGE_KEY = "logger.language"; + private static final String ELEMENT_CACHE = "elementCache.isEnabled"; + private static final String NEW_BOOL_VALUE = "true"; private static final String NEW_STRING_VALUE = "ru"; private static final String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; private static final String NEW_INT_VALUE = "10000"; @@ -26,6 +31,7 @@ public void before() { System.setProperty(LANGUAGE_KEY, NEW_STRING_VALUE); System.setProperty(CONDITION_TIMEOUT_KEY, NEW_INT_VALUE); System.setProperty(RETRY_NUMBER_KEY, NEW_INT_VALUE); + System.setProperty(ELEMENT_CACHE, NEW_BOOL_VALUE); CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); } @@ -47,6 +53,12 @@ public void testShouldBePossibleToOverrideRetryConfigurationWithEnvVariable() { assertEquals(retryNumber, Long.parseLong(NEW_INT_VALUE), "Number of retry attempts should be overridden with env variable"); } + @Test + public void testShouldBePossibleToOverrideElementCacheStateWithEnvVariable() { + boolean isEnabled = CustomAqualityServices.getServiceProvider().getInstance(IElementCacheConfiguration.class).isEnabled(); + assertTrue(isEnabled, "Element cache state should be overridden with env variable"); + } + @Test public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { System.setProperty(CONDITION_TIMEOUT_KEY, NEW_STRING_VALUE); @@ -60,14 +72,15 @@ public void testNumberFormatExceptionShouldBeThrownIfRetryConfigurationIsNotANum } @AfterMethod - public void after(){ + public void after() { System.clearProperty(LANGUAGE_KEY); System.clearProperty(CONDITION_TIMEOUT_KEY); System.clearProperty(RETRY_NUMBER_KEY); + System.clearProperty(ELEMENT_CACHE); CustomAqualityServices.initInjector(new AqualityModule<>(CustomAqualityServices::getApplication)); } - private void checkNumberFormatException(Runnable getNumberAction){ + private void checkNumberFormatException(Runnable getNumberAction) { try { CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); getNumberAction.run(); diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index f76238b..d464978 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -9,6 +9,7 @@ + diff --git a/src/test/resources/settings.custom.json b/src/test/resources/settings.custom.json index bb53339..af6df49 100644 --- a/src/test/resources/settings.custom.json +++ b/src/test/resources/settings.custom.json @@ -11,5 +11,8 @@ }, "logger": { "language": "ru" + }, + "elementCache": { + "isEnabled": false } } diff --git a/src/test/resources/settings.json b/src/test/resources/settings.json index 4271f20..cc2e51d 100644 --- a/src/test/resources/settings.json +++ b/src/test/resources/settings.json @@ -11,5 +11,8 @@ }, "logger": { "language": "en" + }, + "elementCache": { + "isEnabled": false } } diff --git a/src/test/resources/settings.local.json b/src/test/resources/settings.local.json index 4271f20..cc2e51d 100644 --- a/src/test/resources/settings.local.json +++ b/src/test/resources/settings.local.json @@ -11,5 +11,8 @@ }, "logger": { "language": "en" + }, + "elementCache": { + "isEnabled": false } } From adb00bed55251652b05efb6d324e820e4fd44c3a Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 12:29:39 +0300 Subject: [PATCH 19/38] extracted IConditionalWait --- .../core/application/AqualityModule.java | 6 ++ .../localization/ILocalizationManager.java | 16 ++++ .../localization/LocalizationManager.java | 9 ++ .../core/waitings/ConditionalWait.java | 94 +++++++++++++++++++ .../core/waitings/IConditionalWait.java | 60 ++++++++++++ 5 files changed, 185 insertions(+) create mode 100644 src/main/java/aquality/selenium/core/localization/ILocalizationManager.java create mode 100644 src/main/java/aquality/selenium/core/localization/LocalizationManager.java create mode 100644 src/main/java/aquality/selenium/core/waitings/ConditionalWait.java create mode 100644 src/main/java/aquality/selenium/core/waitings/IConditionalWait.java diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 96afc1b..f6b2aa3 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -1,9 +1,13 @@ package aquality.selenium.core.application; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.localization.LocalizationManager; import aquality.selenium.core.logging.Logger; import aquality.selenium.core.configurations.*; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; +import aquality.selenium.core.waitings.ConditionalWait; +import aquality.selenium.core.waitings.IConditionalWait; import com.google.inject.AbstractModule; import com.google.inject.Provider; @@ -27,9 +31,11 @@ protected void configure() { bind(ISettingsFile.class).toInstance(getSettings()); bind(Logger.class).toInstance(Logger.getInstance()); bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); + bind(ILocalizationManager.class).to(LocalizationManager.class); bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); bind(IRetryConfiguration.class).to(RetryConfiguration.class); bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class); + bind(IConditionalWait.class).to(ConditionalWait.class); } /** diff --git a/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java b/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java new file mode 100644 index 0000000..7d3b945 --- /dev/null +++ b/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java @@ -0,0 +1,16 @@ +package aquality.selenium.core.localization; + +/** + * This interface is using for translation messages to different languages + */ +public interface ILocalizationManager { + + /** + * Get localized message from resources by its key. + * + * @param messageKey Key in resource file. + * @param args Arguments, which will be provided to template of localized message. + * @return Localized message. + */ + String getLocalizedMessage(String messageKey, Object... args); +} diff --git a/src/main/java/aquality/selenium/core/localization/LocalizationManager.java b/src/main/java/aquality/selenium/core/localization/LocalizationManager.java new file mode 100644 index 0000000..eb51ff8 --- /dev/null +++ b/src/main/java/aquality/selenium/core/localization/LocalizationManager.java @@ -0,0 +1,9 @@ +package aquality.selenium.core.localization; + +public class LocalizationManager implements ILocalizationManager{ + + @Override + public String getLocalizedMessage(String messageKey, Object... args) { + return null; + } +} diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java new file mode 100644 index 0000000..70f467c --- /dev/null +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -0,0 +1,94 @@ +package aquality.selenium.core.waitings; + +import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import aquality.selenium.core.localization.ILocalizationManager; +import com.google.inject.Inject; +import com.google.inject.Provider; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.support.ui.ExpectedCondition; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.time.Duration; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.BooleanSupplier; + +public class ConditionalWait implements IConditionalWait { + + private IApplication application; + private ITimeoutConfiguration timeoutConfiguration; + private ILocalizationManager localizationManager; + + @Inject + private ConditionalWait(Provider applicationProvider, ITimeoutConfiguration timeoutConfiguration, ILocalizationManager localizationManager) { + application = applicationProvider.get(); + this.timeoutConfiguration = timeoutConfiguration; + this.localizationManager = localizationManager; + } + + @Override + public boolean waitForTrue(BooleanSupplier condition, String message) { + try { + waitForTrue(condition, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), message); + return true; + } catch (TimeoutException e) { + return false; + } + } + + @Override + public void waitForTrue(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message) throws TimeoutException { + if (condition == null) { + throw new IllegalArgumentException(localizationManager.getLocalizedMessage("loc.wait.condition.cant.be.null")); + } + + double startTime = getCurrentTime(); + while (true) { + if (condition.getAsBoolean()) { + return; + } + + double currentTime = getCurrentTime(); + if ((currentTime - startTime) > timeoutInSeconds) { + String exceptionMessage = String.format(localizationManager.getLocalizedMessage("loc.wait.timeout.condition"), timeoutInSeconds, message); + throw new TimeoutException(exceptionMessage); + } + + try { + Thread.sleep(pollingIntervalInMilliseconds); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + + @Override + public T waitFor(ExpectedCondition condition, String message) { + return waitFor(condition, + timeoutConfiguration.getCondition(), + timeoutConfiguration.getPollingInterval(), + message, + Collections.singleton(StaleElementReferenceException.class)); + } + + @Override + public T waitFor(ExpectedCondition condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) { + application.setImplicitWaitTimeout(0, TimeUnit.SECONDS); + WebDriverWait wait = new WebDriverWait(application.getDriver(), timeOutInSeconds); + wait.pollingEvery(Duration.ofMillis(pollingIntervalInMilliseconds)); + wait.withMessage(message); + wait.ignoreAll(exceptionsToIgnore); + try { + return wait.until(condition); + } finally { + application.setImplicitWaitTimeout(timeoutConfiguration.getImplicit(), TimeUnit.SECONDS); + } + } + + private double getCurrentTime() { + return System.nanoTime() / Math.pow(10, 9); + } +} diff --git a/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java new file mode 100644 index 0000000..bfe44da --- /dev/null +++ b/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java @@ -0,0 +1,60 @@ +package aquality.selenium.core.waitings; + +import org.openqa.selenium.support.ui.ExpectedCondition; + +import java.util.Collection; +import java.util.concurrent.TimeoutException; +import java.util.function.BooleanSupplier; +import java.util.function.Function; + +/** + * Utility used to wait for some condition. + */ +public interface IConditionalWait { + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition condition with boolean result (predicate) + * @param message Part of error message in case of Timeout exception + * @return true if the condition has been met during the timeout + */ + boolean waitForTrue(BooleanSupplier condition, String message); + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval + * @param message Part of error message in case of Timeout exception + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + void waitForTrue(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message) throws TimeoutException; + + /** + * Waits for function will be true or return some except false. + * Default timeout condition from settings is using. + * StaleElementReferenceException will be handled by default + * + * @param condition Function for waiting {@link Function} + * @param message the message that will be added to an error in case if the condition is not matched during the timeout + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occurred + */ + T waitFor(ExpectedCondition condition, String message); + + /** + * Waits for function will be true or return some except false. + * + * @param condition Function for waiting {@link Function} + * @param timeOutInSeconds Time-out in seconds + * @param pollingIntervalInMilliseconds interval in milliseconds between checks whether condition match + * @param message the message that will be added to an error in case if the condition is not matched during the timeout + * @param exceptionsToIgnore list of exceptions that should be ignored during waiting + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occured + */ + T waitFor(ExpectedCondition condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore); +} From a9ee1f34c73dc9206ffe92e4ba9ffb2406d518f7 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 12:40:40 +0300 Subject: [PATCH 20/38] merge and test fix --- src/test/java/tests/utilities/SettingsFileTests.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index e911526..f1fcef0 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -22,17 +22,14 @@ public class SettingsFileTests extends BaseProfileTest { private static final String LANGUAGE_ENV_KEY = "logger.language"; private static final String ARGUMENTS_ENV_KEY = "arguments.start"; private static final String PROFILE = "jsontest"; - private static final String PROFILE_KEY = "profile"; private static final String FILE_NAME = String.format("settings.%s.json", PROFILE); private ISettingsFile jsonSettingsFile; - private String previousProfile; private static final Map EXPECTED_LANGUAGES = new HashMap() {{ put("language", "ru"); }}; @BeforeMethod public void before() { - previousProfile = System.getProperty(PROFILE_KEY); System.setProperty(PROFILE_KEY, PROFILE); CustomAqualityServices.initInjector(getTestModule()); jsonSettingsFile = CustomAqualityServices.getServiceProvider().getInstance(ISettingsFile.class); From 8545c568c79908f10e108de1a77b12d55c29ae79 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 13:14:11 +0300 Subject: [PATCH 21/38] application to applications added tests for conditionalWait --- .../AqualityModule.java | 2 +- .../AqualityServices.java | 12 +- .../IApplication.java | 6 +- .../core/waitings/ConditionalWait.java | 2 +- .../application/AqualityServicesTests.java | 2 +- .../application/CustomAqualityServices.java | 4 +- .../tests/application/IApplicationTests.java | 14 +- .../java/tests/application/TestModule.java | 2 +- .../application/browser/AqualityServices.java | 2 +- .../application/browser/BrowserTests.java | 2 +- .../browser/ChromeApplication.java | 2 +- .../windowsApp/ApplicationTests.java | 2 +- .../windowsApp/AqualityServices.java | 2 +- .../windowsApp/WindowsApplication.java | 2 +- .../tests/configurations/BaseProfileTest.java | 2 +- .../configurations/EnvConfigurationTests.java | 2 +- .../ProfileConfigurationTests.java | 2 +- .../utilities/CustomSettingsFileTests.java | 2 +- .../tests/utilities/SettingsFileTests.java | 2 +- .../tests/waitings/ConditionalWaitTests.java | 175 ++++++++++++++++++ src/test/java/utils/TimeUtil.java | 8 + src/test/java/utils/Timer.java | 17 ++ src/test/resources/TestSuite.xml | 1 + 23 files changed, 234 insertions(+), 33 deletions(-) rename src/main/java/aquality/selenium/core/{application => applications}/AqualityModule.java (97%) rename src/main/java/aquality/selenium/core/{application => applications}/AqualityServices.java (81%) rename src/main/java/aquality/selenium/core/{application => applications}/IApplication.java (74%) create mode 100644 src/test/java/tests/waitings/ConditionalWaitTests.java create mode 100644 src/test/java/utils/TimeUtil.java create mode 100644 src/test/java/utils/Timer.java diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/applications/AqualityModule.java similarity index 97% rename from src/main/java/aquality/selenium/core/application/AqualityModule.java rename to src/main/java/aquality/selenium/core/applications/AqualityModule.java index c4d18b9..3f4a96c 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityModule.java @@ -1,4 +1,4 @@ -package aquality.selenium.core.application; +package aquality.selenium.core.applications; import aquality.selenium.core.localization.ILocalizationManager; import aquality.selenium.core.localization.LocalizationManager; diff --git a/src/main/java/aquality/selenium/core/application/AqualityServices.java b/src/main/java/aquality/selenium/core/applications/AqualityServices.java similarity index 81% rename from src/main/java/aquality/selenium/core/application/AqualityServices.java rename to src/main/java/aquality/selenium/core/applications/AqualityServices.java index 4f8d98c..3cc435b 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityServices.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityServices.java @@ -1,4 +1,4 @@ -package aquality.selenium.core.application; +package aquality.selenium.core.applications; import com.google.inject.Guice; import com.google.inject.Injector; @@ -24,14 +24,14 @@ protected > AqualityServices(Provider application } /** - * @return true if the application is already started, false otherwise. + * @return true if the applications is already started, false otherwise. */ protected boolean isAppStarted() { return app != null && app.isStarted(); } /** - * Sets the application instance, saving it to DI container. + * Sets the applications instance, saving it to DI container. * @param application instance to set into container. */ protected void setApp(T application) { @@ -39,9 +39,9 @@ protected void setApp(T application) { } /** - * Returns an existing application or initializes a new one based on passed parameter. - * @param startApplicationFunction function to start the application, where the injector could be used. - * @return started application. + * Returns an existing applications or initializes a new one based on passed parameter. + * @param startApplicationFunction function to start the applications, where the injector could be used. + * @return started applications. */ protected T getApp(Function startApplicationFunction) { if (!isAppStarted()) { diff --git a/src/main/java/aquality/selenium/core/application/IApplication.java b/src/main/java/aquality/selenium/core/applications/IApplication.java similarity index 74% rename from src/main/java/aquality/selenium/core/application/IApplication.java rename to src/main/java/aquality/selenium/core/applications/IApplication.java index 19b3cf9..c171c65 100644 --- a/src/main/java/aquality/selenium/core/application/IApplication.java +++ b/src/main/java/aquality/selenium/core/applications/IApplication.java @@ -1,11 +1,11 @@ -package aquality.selenium.core.application; +package aquality.selenium.core.applications; import org.openqa.selenium.remote.RemoteWebDriver; import java.util.concurrent.TimeUnit; /** - * Interface of any application controlled by Selenium WebDriver API + * Interface of any applications controlled by Selenium WebDriver API */ public interface IApplication { @@ -15,7 +15,7 @@ public interface IApplication { RemoteWebDriver getDriver(); /** - * @return Is the application already running or not. + * @return Is the applications already running or not. */ boolean isStarted(); diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java index 70f467c..4109319 100644 --- a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -1,6 +1,6 @@ package aquality.selenium.core.waitings; -import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.applications.IApplication; import aquality.selenium.core.configurations.ITimeoutConfiguration; import aquality.selenium.core.localization.ILocalizationManager; import com.google.inject.Inject; diff --git a/src/test/java/tests/application/AqualityServicesTests.java b/src/test/java/tests/application/AqualityServicesTests.java index 1c9604b..68b5bb6 100644 --- a/src/test/java/tests/application/AqualityServicesTests.java +++ b/src/test/java/tests/application/AqualityServicesTests.java @@ -1,6 +1,6 @@ package tests.application; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import aquality.selenium.core.logging.Logger; import com.google.inject.ConfigurationException; import com.google.inject.Injector; diff --git a/src/test/java/tests/application/CustomAqualityServices.java b/src/test/java/tests/application/CustomAqualityServices.java index 1c64e42..b34842f 100644 --- a/src/test/java/tests/application/CustomAqualityServices.java +++ b/src/test/java/tests/application/CustomAqualityServices.java @@ -1,7 +1,7 @@ package tests.application; -import aquality.selenium.core.application.AqualityModule; -import aquality.selenium.core.application.AqualityServices; +import aquality.selenium.core.applications.AqualityModule; +import aquality.selenium.core.applications.AqualityServices; import com.google.inject.Injector; import tests.application.browser.ChromeApplication; diff --git a/src/test/java/tests/application/IApplicationTests.java b/src/test/java/tests/application/IApplicationTests.java index de8f90a..c3ded8d 100644 --- a/src/test/java/tests/application/IApplicationTests.java +++ b/src/test/java/tests/application/IApplicationTests.java @@ -1,6 +1,6 @@ package tests.application; -import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.applications.IApplication; import com.google.inject.Injector; import org.testng.Assert; import org.testng.annotations.AfterMethod; @@ -22,7 +22,7 @@ default void testShouldBePossibleToGetApplication() { @Test default void testShouldBePossibleToGetDriver() { - Assert.assertNotNull(getApplication().getDriver(), "should be possible get driver from the application"); + Assert.assertNotNull(getApplication().getDriver(), "should be possible get driver from the applications"); } @Test @@ -42,17 +42,17 @@ default void checkImplicitWaitSetting(int valueInSeconds) { @Test default void testShouldBePossibleToDefineIsStarted() { Assert.assertFalse(isApplicationStarted(), - "application should not be started before getting"); + "applications should not be started before getting"); IApplication application = getApplication(); Assert.assertTrue(application.isStarted(), - "application should be started when got it from the aquality services"); + "applications should be started when got it from the aquality services"); Assert.assertTrue(isApplicationStarted(), - "application should be started when check it's state from the aquality services"); + "applications should be started when check it's state from the aquality services"); application.getDriver().quit(); Assert.assertFalse(application.isStarted(), - "application should not be started after quit"); + "applications should not be started after quit"); Assert.assertFalse(isApplicationStarted(), - "application should not be started when check it's state from the aquality services after quit"); + "applications should not be started when check it's state from the aquality services after quit"); } @AfterMethod diff --git a/src/test/java/tests/application/TestModule.java b/src/test/java/tests/application/TestModule.java index 7f92ef4..a345669 100644 --- a/src/test/java/tests/application/TestModule.java +++ b/src/test/java/tests/application/TestModule.java @@ -1,6 +1,6 @@ package tests.application; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import com.google.inject.Provider; import tests.application.browser.ChromeApplication; diff --git a/src/test/java/tests/application/browser/AqualityServices.java b/src/test/java/tests/application/browser/AqualityServices.java index cf2d6f0..9029834 100644 --- a/src/test/java/tests/application/browser/AqualityServices.java +++ b/src/test/java/tests/application/browser/AqualityServices.java @@ -3,7 +3,7 @@ import com.google.inject.Injector; import io.github.bonigarcia.wdm.WebDriverManager; -public class AqualityServices extends aquality.selenium.core.application.AqualityServices { +public class AqualityServices extends aquality.selenium.core.applications.AqualityServices { private static final ThreadLocal INSTANCE_CONTAINER = ThreadLocal.withInitial(AqualityServices::new); private AqualityServices() { diff --git a/src/test/java/tests/application/browser/BrowserTests.java b/src/test/java/tests/application/browser/BrowserTests.java index ed3e356..0b731c0 100644 --- a/src/test/java/tests/application/browser/BrowserTests.java +++ b/src/test/java/tests/application/browser/BrowserTests.java @@ -1,6 +1,6 @@ package tests.application.browser; -import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.applications.IApplication; import com.google.inject.Injector; import tests.application.IApplicationTests; diff --git a/src/test/java/tests/application/browser/ChromeApplication.java b/src/test/java/tests/application/browser/ChromeApplication.java index dd4103f..17d71c0 100644 --- a/src/test/java/tests/application/browser/ChromeApplication.java +++ b/src/test/java/tests/application/browser/ChromeApplication.java @@ -1,6 +1,6 @@ package tests.application.browser; -import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.applications.IApplication; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.remote.RemoteWebDriver; diff --git a/src/test/java/tests/application/windowsApp/ApplicationTests.java b/src/test/java/tests/application/windowsApp/ApplicationTests.java index c5c8f9a..478a754 100644 --- a/src/test/java/tests/application/windowsApp/ApplicationTests.java +++ b/src/test/java/tests/application/windowsApp/ApplicationTests.java @@ -1,6 +1,6 @@ package tests.application.windowsApp; -import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.applications.IApplication; import com.google.inject.Injector; import tests.application.IApplicationTests; diff --git a/src/test/java/tests/application/windowsApp/AqualityServices.java b/src/test/java/tests/application/windowsApp/AqualityServices.java index 20d7ee0..1bffd51 100644 --- a/src/test/java/tests/application/windowsApp/AqualityServices.java +++ b/src/test/java/tests/application/windowsApp/AqualityServices.java @@ -7,7 +7,7 @@ import java.io.IOException; import java.net.URL; -public class AqualityServices extends aquality.selenium.core.application.AqualityServices { +public class AqualityServices extends aquality.selenium.core.applications.AqualityServices { private static final ThreadLocal INSTANCE_CONTAINER = ThreadLocal.withInitial(AqualityServices::new); private static final String APP_PATH = "./src/test/resources/apps/Day Maxi Calc.exe"; private static final String DEFAULT_SERVICE_URL = "http://127.0.0.1:4723/"; diff --git a/src/test/java/tests/application/windowsApp/WindowsApplication.java b/src/test/java/tests/application/windowsApp/WindowsApplication.java index ac3a162..84b38d2 100644 --- a/src/test/java/tests/application/windowsApp/WindowsApplication.java +++ b/src/test/java/tests/application/windowsApp/WindowsApplication.java @@ -1,6 +1,6 @@ package tests.application.windowsApp; -import aquality.selenium.core.application.IApplication; +import aquality.selenium.core.applications.IApplication; import io.appium.java_client.windows.WindowsDriver; import io.appium.java_client.windows.WindowsElement; import org.openqa.selenium.remote.DesiredCapabilities; diff --git a/src/test/java/tests/configurations/BaseProfileTest.java b/src/test/java/tests/configurations/BaseProfileTest.java index f276ec5..32e7201 100644 --- a/src/test/java/tests/configurations/BaseProfileTest.java +++ b/src/test/java/tests/configurations/BaseProfileTest.java @@ -9,7 +9,7 @@ public class BaseProfileTest { private String previousProfile; @BeforeMethod - public void before() { + public void before1() { previousProfile = System.getProperty(PROFILE_KEY); } diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 293ea64..d396e56 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -1,6 +1,6 @@ package tests.configurations; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import aquality.selenium.core.configurations.IElementCacheConfiguration; import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.configurations.IRetryConfiguration; diff --git a/src/test/java/tests/configurations/ProfileConfigurationTests.java b/src/test/java/tests/configurations/ProfileConfigurationTests.java index f0a3746..39bfc13 100644 --- a/src/test/java/tests/configurations/ProfileConfigurationTests.java +++ b/src/test/java/tests/configurations/ProfileConfigurationTests.java @@ -1,6 +1,6 @@ package tests.configurations; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.localization.SupportedLanguage; import org.testng.annotations.BeforeMethod; diff --git a/src/test/java/tests/utilities/CustomSettingsFileTests.java b/src/test/java/tests/utilities/CustomSettingsFileTests.java index 69b0c23..d49ccfb 100644 --- a/src/test/java/tests/utilities/CustomSettingsFileTests.java +++ b/src/test/java/tests/utilities/CustomSettingsFileTests.java @@ -1,6 +1,6 @@ package tests.utilities; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import aquality.selenium.core.utilities.ISettingsFile; import com.google.inject.Provider; import org.testng.Assert; diff --git a/src/test/java/tests/utilities/SettingsFileTests.java b/src/test/java/tests/utilities/SettingsFileTests.java index f1fcef0..15397b6 100644 --- a/src/test/java/tests/utilities/SettingsFileTests.java +++ b/src/test/java/tests/utilities/SettingsFileTests.java @@ -1,6 +1,6 @@ package tests.utilities; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import aquality.selenium.core.utilities.ISettingsFile; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; diff --git a/src/test/java/tests/waitings/ConditionalWaitTests.java b/src/test/java/tests/waitings/ConditionalWaitTests.java new file mode 100644 index 0000000..174805d --- /dev/null +++ b/src/test/java/tests/waitings/ConditionalWaitTests.java @@ -0,0 +1,175 @@ +package tests.waitings; + +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import aquality.selenium.core.waitings.IConditionalWait; +import org.openqa.selenium.StaleElementReferenceException; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import utils.Timer; + +import java.util.Collections; +import java.util.concurrent.TimeoutException; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class ConditionalWaitTests { + + private static final long waitForTimeoutCondition = 10; + private static final long waitForTimeoutPolling = 150; + private Timer timer; + private ITimeoutConfiguration timeoutConfiguration; + private IConditionalWait conditionalWait; + + @BeforeMethod + public void init() { + timeoutConfiguration = CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class); + conditionalWait = CustomAqualityServices.getServiceProvider().getInstance(IConditionalWait.class); + timer = new Timer(); + } + + @AfterMethod + public void quitApplication() { + CustomAqualityServices.getApplication().getDriver().quit(); + } + + @Test + public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { + long timeoutCondition = timeoutConfiguration.getCondition(); + boolean result = conditionalWait.waitForTrue(() -> + { + timer.start(); + return false; + }, "Condition should be true"); + double duration = timer.stop(); + + assertFalse(result); + assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition); + } + + @Test + public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() { + try { + conditionalWait.waitForTrue(() -> + { + timer.start(); + return false; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); + } catch (TimeoutException e) { + double duration = timer.stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition); + } + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeoutIsNotOver() { + long timeoutCondition = timeoutConfiguration.getCondition(); + + boolean result = conditionalWait.waitForTrue(() -> + { + timer.start(); + return true; + }, "Timeout exception should not be thrown"); + double duration = timer.stop(); + + assertTrue(result); + assertTrue(duration < timeoutCondition); + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOver() throws TimeoutException { + conditionalWait.waitForTrue(() -> + { + timer.start(); + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); + double duration = timer.stop(); + + assertTrue(duration < waitForTimeoutCondition); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNullCannotBePassedAsCondition() { + conditionalWait.waitForTrue(null, "Condition should not be null"); + } + + @Test + public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaultTimeoutIsOver() { + long timeoutCondition = timeoutConfiguration.getCondition(); + try { + conditionalWait.waitFor((driver) -> + { + timer.start(); + return false; + }, + "Condition should be true"); + + } catch (org.openqa.selenium.TimeoutException e) { + double duration = timer.stop(); + + assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition); + } + } + + @Test + public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeoutIsOver() { + try { + conditionalWait.waitFor((driver) -> + { + timer.start(); + return false; + }, waitForTimeoutCondition, waitForTimeoutPolling, + "Conditional should be true", Collections.singleton(StaleElementReferenceException.class)); + + } catch (org.openqa.selenium.TimeoutException e) { + double duration = timer.stop(); + + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition); + + } + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndDefaultTimeoutIsNotOver() { + conditionalWait.waitFor((driver) -> + { + timer.start(); + return true; + }, + "Conditional should be true"); + double duration = timer.stop(); + + assertTrue(duration < timeoutConfiguration.getCondition()); + } + + @Test + public void testExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver() { + try { + conditionalWait.waitFor((driver) -> + { + timer.start(); + throw new IllegalArgumentException("I am exception"); + }, waitForTimeoutCondition, waitForTimeoutPolling, + "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); + } catch (org.openqa.selenium.TimeoutException e) { + double duration = timer.stop(); + + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition); + } + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOver() { + conditionalWait.waitFor((driver) -> + { + timer.start(); + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, + "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); + double duration = timer.stop(); + + assertTrue(duration < waitForTimeoutCondition); + } +} diff --git a/src/test/java/utils/TimeUtil.java b/src/test/java/utils/TimeUtil.java new file mode 100644 index 0000000..76fc87a --- /dev/null +++ b/src/test/java/utils/TimeUtil.java @@ -0,0 +1,8 @@ +package utils; + +public class TimeUtil { + + public static double getCurrentTimeInSeconds() { + return System.nanoTime() / Math.pow(10, 9); + } +} diff --git a/src/test/java/utils/Timer.java b/src/test/java/utils/Timer.java new file mode 100644 index 0000000..42c0f56 --- /dev/null +++ b/src/test/java/utils/Timer.java @@ -0,0 +1,17 @@ +package utils; + +import static utils.TimeUtil.*; + +public class Timer { + private double startTime; + + public void start(){ + if(startTime == 0){ + startTime = getCurrentTimeInSeconds(); + } + } + + public double stop(){ + return getCurrentTimeInSeconds() - startTime; + } +} \ No newline at end of file diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index d464978..6af14e5 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -10,6 +10,7 @@ + From 6266fd3d958bfa7a12838c8137cbe62a4fcc71c2 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 14:06:33 +0300 Subject: [PATCH 22/38] removed SupportedLanguaged and added default language if configuration is absent --- .../configurations/ILoggerConfiguration.java | 8 +++----- .../configurations/LoggerConfiguration.java | 7 ++++--- .../core/localization/SupportedLanguage.java | 5 ----- .../core/utilities/SettingsFileUtil.java | 11 +++++++++++ .../tests/configurations/BaseProfileTest.java | 4 ++-- .../configurations/EnvConfigurationTests.java | 15 ++++++++++++--- .../LoggerConfigurationTests.java | 6 +++--- .../ProfileConfigurationTests.java | 6 ++---- src/test/resources/settings.empty.json | 2 ++ src/test/resources/settings.json | 18 ------------------ 10 files changed, 39 insertions(+), 43 deletions(-) delete mode 100644 src/main/java/aquality/selenium/core/localization/SupportedLanguage.java create mode 100644 src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java create mode 100644 src/test/resources/settings.empty.json delete mode 100644 src/test/resources/settings.json diff --git a/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java b/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java index 741c72d..c472eca 100644 --- a/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java +++ b/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java @@ -1,16 +1,14 @@ package aquality.selenium.core.configurations; -import aquality.selenium.core.localization.SupportedLanguage; - /** * Describes logger configuration. */ public interface ILoggerConfiguration { /** - * Gets language of framework. + * Gets language of the library. * - * @return Supported language. + * @return Language. */ - SupportedLanguage getLanguage(); + String getLanguage(); } diff --git a/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java b/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java index 3f57ab8..e8e1b1a 100644 --- a/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java +++ b/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java @@ -1,11 +1,12 @@ package aquality.selenium.core.configurations; -import aquality.selenium.core.localization.SupportedLanguage; import aquality.selenium.core.utilities.ISettingsFile; +import aquality.selenium.core.utilities.SettingsFileUtil; import com.google.inject.Inject; public class LoggerConfiguration implements ILoggerConfiguration{ + private static final String DEFAULT_LANGUAGE = "en"; private final ISettingsFile settingsFile; @Inject @@ -14,7 +15,7 @@ public LoggerConfiguration(ISettingsFile settingsFile){ } @Override - public SupportedLanguage getLanguage() { - return SupportedLanguage.valueOf(settingsFile.getValue("/logger/language").toString().toUpperCase()); + public String getLanguage() { + return SettingsFileUtil.getValueOrDefault(settingsFile, "/logger/language", DEFAULT_LANGUAGE).toString(); } } diff --git a/src/main/java/aquality/selenium/core/localization/SupportedLanguage.java b/src/main/java/aquality/selenium/core/localization/SupportedLanguage.java deleted file mode 100644 index 1ff75cc..0000000 --- a/src/main/java/aquality/selenium/core/localization/SupportedLanguage.java +++ /dev/null @@ -1,5 +0,0 @@ -package aquality.selenium.core.localization; - -public enum SupportedLanguage { - EN,RU -} diff --git a/src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java b/src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java new file mode 100644 index 0000000..eb9f67e --- /dev/null +++ b/src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java @@ -0,0 +1,11 @@ +package aquality.selenium.core.utilities; + +public class SettingsFileUtil { + + private SettingsFileUtil() { + } + + public static Object getValueOrDefault(ISettingsFile settingsFile, String path, Object defaultValue) { + return settingsFile.isValuePresent(path) ? settingsFile.getValue(path) : defaultValue; + } +} diff --git a/src/test/java/tests/configurations/BaseProfileTest.java b/src/test/java/tests/configurations/BaseProfileTest.java index f276ec5..6ecb378 100644 --- a/src/test/java/tests/configurations/BaseProfileTest.java +++ b/src/test/java/tests/configurations/BaseProfileTest.java @@ -9,12 +9,12 @@ public class BaseProfileTest { private String previousProfile; @BeforeMethod - public void before() { + public void saveProfile() { previousProfile = System.getProperty(PROFILE_KEY); } @AfterMethod - public void after() { + public void restoreProfile() { if (previousProfile == null) { System.clearProperty(PROFILE_KEY); } else { diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 293ea64..982a246 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -5,7 +5,6 @@ import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.configurations.IRetryConfiguration; import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.localization.SupportedLanguage; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -22,6 +21,7 @@ public class EnvConfigurationTests extends BaseProfileTest { private static final String ELEMENT_CACHE = "elementCache.isEnabled"; private static final String NEW_BOOL_VALUE = "true"; private static final String NEW_STRING_VALUE = "ru"; + private static final String DEFAULT_LANGUAGE = "en"; private static final String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; private static final String NEW_INT_VALUE = "10000"; private static final String RETRY_NUMBER_KEY = "retry.number"; @@ -37,8 +37,8 @@ public void before() { @Test public void testShouldBePossibleToOverrideLanguageWithEnvVariable() { - SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); - assertEquals(language, SupportedLanguage.RU, "Current language should be overridden with env variable"); + String language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, "ru", "Current language should be overridden with env variable"); } @Test @@ -71,6 +71,15 @@ public void testNumberFormatExceptionShouldBeThrownIfRetryConfigurationIsNotANum checkNumberFormatException(() -> CustomAqualityServices.getServiceProvider().getInstance(IRetryConfiguration.class).getNumber()); } + @Test + public void testShouldGetDefaultLanguageIfConfigurationIsAbsent() { + System.setProperty(PROFILE_KEY, "empty"); + System.clearProperty(LANGUAGE_KEY); + CustomAqualityServices.initInjector(new TestModule(CustomAqualityServices::getApplication)); + String language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, DEFAULT_LANGUAGE, "Current language should be got from logger configuration"); + } + @AfterMethod public void after() { System.clearProperty(LANGUAGE_KEY); diff --git a/src/test/java/tests/configurations/LoggerConfigurationTests.java b/src/test/java/tests/configurations/LoggerConfigurationTests.java index f6caa67..de673d2 100644 --- a/src/test/java/tests/configurations/LoggerConfigurationTests.java +++ b/src/test/java/tests/configurations/LoggerConfigurationTests.java @@ -1,16 +1,16 @@ package tests.configurations; import aquality.selenium.core.configurations.ILoggerConfiguration; -import aquality.selenium.core.localization.SupportedLanguage; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; + import static org.testng.Assert.assertEquals; public class LoggerConfigurationTests { @Test public void testShouldBePossibleToGetLanguage() { - SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); - assertEquals(language, SupportedLanguage.EN, "Current language should be got from logger configuration"); + String language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, "en", "Current language should be got from logger configuration"); } } diff --git a/src/test/java/tests/configurations/ProfileConfigurationTests.java b/src/test/java/tests/configurations/ProfileConfigurationTests.java index f0a3746..4819c0c 100644 --- a/src/test/java/tests/configurations/ProfileConfigurationTests.java +++ b/src/test/java/tests/configurations/ProfileConfigurationTests.java @@ -2,7 +2,6 @@ import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.configurations.ILoggerConfiguration; -import aquality.selenium.core.localization.SupportedLanguage; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; @@ -21,8 +20,7 @@ public void before() { @Test public void testShouldBePossibleToGetLanguageFromNewSettingsFile() { - - SupportedLanguage language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); - assertEquals(language, SupportedLanguage.RU, String.format("Current language should be got from %s profile", PROFILE)); + String language = CustomAqualityServices.getServiceProvider().getInstance(ILoggerConfiguration.class).getLanguage(); + assertEquals(language, "ru", String.format("Current language should be got from %s profile", PROFILE)); } } diff --git a/src/test/resources/settings.empty.json b/src/test/resources/settings.empty.json new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/src/test/resources/settings.empty.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/test/resources/settings.json b/src/test/resources/settings.json deleted file mode 100644 index cc2e51d..0000000 --- a/src/test/resources/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "timeouts": { - "timeoutImplicit": 0, - "timeoutCondition": 30, - "timeoutPollingInterval": 300, - "timeoutCommand": 60 - }, - "retry": { - "number": 2, - "pollingInterval": 300 - }, - "logger": { - "language": "en" - }, - "elementCache": { - "isEnabled": false - } -} From 6093c7668a4cbbb7b44a486f772b008365268aca Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 15:29:41 +0300 Subject: [PATCH 23/38] support multiple threads in ConditionalWaitTests added friendly messages to the tests --- .../localization/LocalizationManager.java | 2 +- .../tests/waitings/ConditionalWaitTests.java | 89 ++++++++++--------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/main/java/aquality/selenium/core/localization/LocalizationManager.java b/src/main/java/aquality/selenium/core/localization/LocalizationManager.java index eb51ff8..c075b80 100644 --- a/src/main/java/aquality/selenium/core/localization/LocalizationManager.java +++ b/src/main/java/aquality/selenium/core/localization/LocalizationManager.java @@ -4,6 +4,6 @@ public class LocalizationManager implements ILocalizationManager{ @Override public String getLocalizedMessage(String messageKey, Object... args) { - return null; + return ""; } } diff --git a/src/test/java/tests/waitings/ConditionalWaitTests.java b/src/test/java/tests/waitings/ConditionalWaitTests.java index 174805d..ffae995 100644 --- a/src/test/java/tests/waitings/ConditionalWaitTests.java +++ b/src/test/java/tests/waitings/ConditionalWaitTests.java @@ -19,7 +19,7 @@ public class ConditionalWaitTests { private static final long waitForTimeoutCondition = 10; private static final long waitForTimeoutPolling = 150; - private Timer timer; + private ThreadLocal timer = ThreadLocal.withInitial(Timer::new); private ITimeoutConfiguration timeoutConfiguration; private IConditionalWait conditionalWait; @@ -27,7 +27,6 @@ public class ConditionalWaitTests { public void init() { timeoutConfiguration = CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class); conditionalWait = CustomAqualityServices.getServiceProvider().getInstance(IConditionalWait.class); - timer = new Timer(); } @AfterMethod @@ -40,13 +39,14 @@ public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver( long timeoutCondition = timeoutConfiguration.getCondition(); boolean result = conditionalWait.waitForTrue(() -> { - timer.start(); + timer.get().start(); return false; }, "Condition should be true"); - double duration = timer.stop(); - - assertFalse(result); - assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition); + double duration = timer.get().stop(); + assertFalse(result, "waitForTrue should return false when condition is not satisfied."); + assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition, + String.format("Duration '%s' should be between timeoutCondition '%s' and 2*timeoutCondition when condition is not satisfied.", + duration, timeoutCondition)); } @Test @@ -54,12 +54,14 @@ public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() try { conditionalWait.waitForTrue(() -> { - timer.start(); + timer.get().start(); return false; }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); } catch (TimeoutException e) { - double duration = timer.stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition); + double duration = timer.get().stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, + String.format("Duration '%s' should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition when condition is not satisfied.", + duration, waitForTimeoutCondition)); } } @@ -69,25 +71,27 @@ public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeo boolean result = conditionalWait.waitForTrue(() -> { - timer.start(); + timer.get().start(); return true; }, "Timeout exception should not be thrown"); - double duration = timer.stop(); - - assertTrue(result); - assertTrue(duration < timeoutCondition); + double duration = timer.get().stop(); + assertTrue(result, "waitForTrue should return true when condition is satisfied."); + assertTrue(duration < timeoutCondition, + String.format("Duration '%s' should be less than timeoutCondition '%s' when condition is satisfied.", + duration, timeoutCondition)); } @Test public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOver() throws TimeoutException { conditionalWait.waitForTrue(() -> { - timer.start(); + timer.get().start(); return true; }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); - double duration = timer.stop(); - - assertTrue(duration < waitForTimeoutCondition); + double duration = timer.get().stop(); + assertTrue(duration < waitForTimeoutCondition, + String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", + duration, waitForTimeoutCondition)); } @Test(expectedExceptions = IllegalArgumentException.class) @@ -101,15 +105,15 @@ public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaul try { conditionalWait.waitFor((driver) -> { - timer.start(); + timer.get().start(); return false; }, "Condition should be true"); - } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.stop(); - - assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition); + double duration = timer.get().stop(); + assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition, + String.format("Duration '%s' before throwing should be between timeoutCondition '%s' and 2*timeoutCondition ", + duration, timeoutCondition)); } } @@ -118,16 +122,16 @@ public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeou try { conditionalWait.waitFor((driver) -> { - timer.start(); + timer.get().start(); return false; }, waitForTimeoutCondition, waitForTimeoutPolling, "Conditional should be true", Collections.singleton(StaleElementReferenceException.class)); } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.stop(); - - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition); - + double duration = timer.get().stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, + String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", + duration, waitForTimeoutCondition)); } } @@ -135,13 +139,14 @@ public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeou public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndDefaultTimeoutIsNotOver() { conditionalWait.waitFor((driver) -> { - timer.start(); + timer.get().start(); return true; }, "Conditional should be true"); - double duration = timer.stop(); - - assertTrue(duration < timeoutConfiguration.getCondition()); + double duration = timer.get().stop(); + assertTrue(duration < timeoutConfiguration.getCondition(), + String.format("Duration '%s' should be less than condition timeout '%s' when condition is satisfied.", + duration, timeoutConfiguration.getCondition())); } @Test @@ -149,14 +154,15 @@ public void testExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver( try { conditionalWait.waitFor((driver) -> { - timer.start(); + timer.get().start(); throw new IllegalArgumentException("I am exception"); }, waitForTimeoutCondition, waitForTimeoutPolling, "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.stop(); - - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition); + double duration = timer.get().stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, + String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", + duration, waitForTimeoutCondition)); } } @@ -164,12 +170,13 @@ public void testExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver( public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOver() { conditionalWait.waitFor((driver) -> { - timer.start(); + timer.get().start(); return true; }, waitForTimeoutCondition, waitForTimeoutPolling, "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); - double duration = timer.stop(); - - assertTrue(duration < waitForTimeoutCondition); + double duration = timer.get().stop(); + assertTrue(duration < waitForTimeoutCondition, + String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", + duration, waitForTimeoutCondition)); } } From ee3383c8379e3e1e776329680c63025a3e1574d2 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 15:58:27 +0300 Subject: [PATCH 24/38] register configuration as singleton --- .../selenium/core/application/AqualityModule.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/aquality/selenium/core/application/AqualityModule.java b/src/main/java/aquality/selenium/core/application/AqualityModule.java index 41ee181..2e44633 100644 --- a/src/main/java/aquality/selenium/core/application/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/application/AqualityModule.java @@ -6,6 +6,7 @@ import aquality.selenium.core.configurations.*; import com.google.inject.AbstractModule; import com.google.inject.Provider; +import com.google.inject.Singleton; /** * Describes all dependencies which is registered for the project. @@ -26,10 +27,10 @@ protected void configure() { bind(IApplication.class).toProvider(applicationProvider); bind(ISettingsFile.class).toInstance(getSettings()); bind(Logger.class).toInstance(Logger.getInstance()); - bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); - bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); - bind(IRetryConfiguration.class).to(RetryConfiguration.class); - bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class); + bind(ILoggerConfiguration.class).to(LoggerConfiguration.class).in(Singleton.class); + bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class).in(Singleton.class); + bind(IRetryConfiguration.class).to(RetryConfiguration.class).in(Singleton.class); + bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class).in(Singleton.class); } /** From 42446007f37151e8aa4238b4a3657b84d5b60239 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 17:09:37 +0300 Subject: [PATCH 25/38] fixed comments --- .../core/configurations/ElementCacheConfiguration.java | 4 ++-- .../core/configurations/ILoggerConfiguration.java | 5 ++--- .../core/configurations/TimeoutConfiguration.java | 10 +++++----- .../tests/configurations/EnvConfigurationTests.java | 1 - 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java b/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java index 959ff7b..1e9a160 100644 --- a/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java +++ b/src/main/java/aquality/selenium/core/configurations/ElementCacheConfiguration.java @@ -5,12 +5,12 @@ public class ElementCacheConfiguration implements IElementCacheConfiguration{ - private static final String JSON_PATH = "/elementCache/isEnabled"; + private static final String IS_ENABLED_PATH = "/elementCache/isEnabled"; private boolean isEnabled; @Inject public ElementCacheConfiguration(ISettingsFile settingsFile){ - isEnabled = settingsFile.isValuePresent(JSON_PATH) && Boolean.valueOf(settingsFile.getValue(JSON_PATH).toString()); + isEnabled = settingsFile.isValuePresent(IS_ENABLED_PATH) && Boolean.valueOf(settingsFile.getValue(IS_ENABLED_PATH).toString()); } @Override diff --git a/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java b/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java index c472eca..99af3c8 100644 --- a/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java +++ b/src/main/java/aquality/selenium/core/configurations/ILoggerConfiguration.java @@ -6,9 +6,8 @@ public interface ILoggerConfiguration { /** - * Gets language of the library. - * - * @return Language. + * Gets language used inside the library for logging. + * @return language used for logging. */ String getLanguage(); } diff --git a/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java b/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java index 34088ce..b5d8cd9 100644 --- a/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java +++ b/src/main/java/aquality/selenium/core/configurations/TimeoutConfiguration.java @@ -21,7 +21,7 @@ public TimeoutConfiguration(ISettingsFile settingsFile) { } private long getTimeout(TIMEOUT timeout){ - return Long.valueOf(settingsFile.getValue("/timeouts/" + timeout.getKey()).toString()); + return Long.valueOf(settingsFile.getValue(timeout.getKey()).toString()); } public long getImplicit(){ @@ -41,10 +41,10 @@ public long getCommand(){ } private enum TIMEOUT { - IMPLICIT("timeoutImplicit"), - CONDITION("timeoutCondition"), - POLL_INTERVAL("timeoutPollingInterval"), - COMMAND("timeoutCommand"); + IMPLICIT("/timeouts/timeoutImplicit"), + CONDITION("/timeouts/timeoutCondition"), + POLL_INTERVAL("/timeouts/timeoutPollingInterval"), + COMMAND("/timeouts/timeoutCommand"); private String key; TIMEOUT(String key){ diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 982a246..5f3d9e8 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -95,7 +95,6 @@ private void checkNumberFormatException(Runnable getNumberAction) { getNumberAction.run(); } catch (Exception e) { Assert.assertSame(e.getCause().getClass(), NumberFormatException.class); - Assert.assertTrue(e.getMessage().contains("NumberFormatException")); } } } From 327a6828176293d5e3959a260024c000ed008b60 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 17:24:10 +0300 Subject: [PATCH 26/38] moved SettingsFileUtil to ISettingsFile --- .../core/configurations/LoggerConfiguration.java | 5 ++--- .../selenium/core/utilities/ISettingsFile.java | 11 +++++++++++ .../selenium/core/utilities/SettingsFileUtil.java | 11 ----------- 3 files changed, 13 insertions(+), 14 deletions(-) delete mode 100644 src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java diff --git a/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java b/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java index e8e1b1a..cb09a51 100644 --- a/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java +++ b/src/main/java/aquality/selenium/core/configurations/LoggerConfiguration.java @@ -1,10 +1,9 @@ package aquality.selenium.core.configurations; import aquality.selenium.core.utilities.ISettingsFile; -import aquality.selenium.core.utilities.SettingsFileUtil; import com.google.inject.Inject; -public class LoggerConfiguration implements ILoggerConfiguration{ +public class LoggerConfiguration implements ILoggerConfiguration { private static final String DEFAULT_LANGUAGE = "en"; private final ISettingsFile settingsFile; @@ -16,6 +15,6 @@ public LoggerConfiguration(ISettingsFile settingsFile){ @Override public String getLanguage() { - return SettingsFileUtil.getValueOrDefault(settingsFile, "/logger/language", DEFAULT_LANGUAGE).toString(); + return settingsFile.getValueOrDefault("/logger/language", DEFAULT_LANGUAGE).toString(); } } diff --git a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java index a67987b..590e270 100644 --- a/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java +++ b/src/main/java/aquality/selenium/core/utilities/ISettingsFile.java @@ -39,4 +39,15 @@ public interface ISettingsFile { * @return True if exists, false otherwise. */ boolean isValuePresent(String path); + + /** + * Gets value from settings file or default value. + * + * @param path Path to the values. Depending on file format, it can be jsonPath, xpath etc. + * @param defaultValue will be returned if there is no value by path in settings file. + * @return Value from settings file or default value. + */ + default Object getValueOrDefault(String path, Object defaultValue) { + return this.isValuePresent(path) ? this.getValue(path) : defaultValue; + } } diff --git a/src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java b/src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java deleted file mode 100644 index eb9f67e..0000000 --- a/src/main/java/aquality/selenium/core/utilities/SettingsFileUtil.java +++ /dev/null @@ -1,11 +0,0 @@ -package aquality.selenium.core.utilities; - -public class SettingsFileUtil { - - private SettingsFileUtil() { - } - - public static Object getValueOrDefault(ISettingsFile settingsFile, String path, Object defaultValue) { - return settingsFile.isValuePresent(path) ? settingsFile.getValue(path) : defaultValue; - } -} From 70c1b01d6f668e7c37a9c576ab23bd547de20b03 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 17:58:08 +0300 Subject: [PATCH 27/38] added IWaitingsModule --- .../selenium/core/applications/AqualityModule.java | 6 +++--- .../selenium/core/waitings/IWaitingsModule.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java diff --git a/src/main/java/aquality/selenium/core/applications/AqualityModule.java b/src/main/java/aquality/selenium/core/applications/AqualityModule.java index 3f4a96c..490c02f 100644 --- a/src/main/java/aquality/selenium/core/applications/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityModule.java @@ -5,16 +5,16 @@ import aquality.selenium.core.logging.Logger; import aquality.selenium.core.utilities.ISettingsFile; import aquality.selenium.core.utilities.JsonSettingsFile; -import aquality.selenium.core.waitings.ConditionalWait; import aquality.selenium.core.waitings.IConditionalWait; import aquality.selenium.core.configurations.*; +import aquality.selenium.core.waitings.IWaitingsModule; import com.google.inject.AbstractModule; import com.google.inject.Provider; /** * Describes all dependencies which is registered for the project. */ -public class AqualityModule extends AbstractModule { +public class AqualityModule extends AbstractModule implements IWaitingsModule { private final Provider applicationProvider; @@ -35,7 +35,7 @@ protected void configure() { bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); bind(IRetryConfiguration.class).to(RetryConfiguration.class); bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class); - bind(IConditionalWait.class).to(ConditionalWait.class); + bind(IConditionalWait.class).to(getConditionalWaitImplementation()); } /** diff --git a/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java b/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java new file mode 100644 index 0000000..808cdb1 --- /dev/null +++ b/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java @@ -0,0 +1,14 @@ +package aquality.selenium.core.waitings; + +/** + * Provides implementations for waitings module. + */ +public interface IWaitingsModule { + + /** + * @return implementation of {@link IConditionalWait} + */ + default Class getConditionalWaitImplementation() { + return ConditionalWait.class; + } +} From a88af112877ac7900f390f48a4168b855d6ea7ac Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 18:01:43 +0300 Subject: [PATCH 28/38] small fix in summary --- .../selenium/core/localization/ILocalizationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java b/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java index 7d3b945..13d6981 100644 --- a/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java +++ b/src/main/java/aquality/selenium/core/localization/ILocalizationManager.java @@ -6,7 +6,7 @@ public interface ILocalizationManager { /** - * Get localized message from resources by its key. + * Gets localized message from resources by its key. * * @param messageKey Key in resource file. * @param args Arguments, which will be provided to template of localized message. From 60f56a4014904429c1d3df6734614ad0a21fb20b Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 18:21:56 +0300 Subject: [PATCH 29/38] merge --- .../aquality/selenium/core/applications/AqualityModule.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/aquality/selenium/core/applications/AqualityModule.java b/src/main/java/aquality/selenium/core/applications/AqualityModule.java index 40728d9..623305b 100644 --- a/src/main/java/aquality/selenium/core/applications/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityModule.java @@ -35,11 +35,7 @@ protected void configure() { bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class).in(Singleton.class); bind(IRetryConfiguration.class).to(RetryConfiguration.class).in(Singleton.class); bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class).in(Singleton.class); - bind(ILoggerConfiguration.class).to(LoggerConfiguration.class); bind(ILocalizationManager.class).to(LocalizationManager.class); - bind(ITimeoutConfiguration.class).to(TimeoutConfiguration.class); - bind(IRetryConfiguration.class).to(RetryConfiguration.class); - bind(IElementCacheConfiguration.class).to(ElementCacheConfiguration.class); bind(IConditionalWait.class).to(getConditionalWaitImplementation()); } From 84365cf240e3e777a54e05c39fea293fe021c903 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 18:30:21 +0300 Subject: [PATCH 30/38] update doc --- .../java/aquality/selenium/core/waitings/IWaitingsModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java b/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java index 808cdb1..c73bdb0 100644 --- a/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java +++ b/src/main/java/aquality/selenium/core/waitings/IWaitingsModule.java @@ -6,7 +6,7 @@ public interface IWaitingsModule { /** - * @return implementation of {@link IConditionalWait} + * @return implementation of {@link IConditionalWait}. */ default Class getConditionalWaitImplementation() { return ConditionalWait.class; From 0b3e61bc920c35c5b37e2fcf68b69b42379bc2e4 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Thu, 30 Jan 2020 18:34:10 +0300 Subject: [PATCH 31/38] rename applications to application in docs --- .../selenium/core/applications/AqualityServices.java | 10 +++++----- .../selenium/core/applications/IApplication.java | 4 ++-- .../java/tests/application/IApplicationTests.java | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/aquality/selenium/core/applications/AqualityServices.java b/src/main/java/aquality/selenium/core/applications/AqualityServices.java index 3cc435b..03572d2 100644 --- a/src/main/java/aquality/selenium/core/applications/AqualityServices.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityServices.java @@ -24,14 +24,14 @@ protected > AqualityServices(Provider application } /** - * @return true if the applications is already started, false otherwise. + * @return true if the application is already started, false otherwise. */ protected boolean isAppStarted() { return app != null && app.isStarted(); } /** - * Sets the applications instance, saving it to DI container. + * Sets the application instance, saving it to DI container. * @param application instance to set into container. */ protected void setApp(T application) { @@ -39,9 +39,9 @@ protected void setApp(T application) { } /** - * Returns an existing applications or initializes a new one based on passed parameter. - * @param startApplicationFunction function to start the applications, where the injector could be used. - * @return started applications. + * Returns an existing application or initializes a new one based on passed parameter. + * @param startApplicationFunction function to start the application, where the injector could be used. + * @return started application. */ protected T getApp(Function startApplicationFunction) { if (!isAppStarted()) { diff --git a/src/main/java/aquality/selenium/core/applications/IApplication.java b/src/main/java/aquality/selenium/core/applications/IApplication.java index c171c65..6b61943 100644 --- a/src/main/java/aquality/selenium/core/applications/IApplication.java +++ b/src/main/java/aquality/selenium/core/applications/IApplication.java @@ -5,7 +5,7 @@ import java.util.concurrent.TimeUnit; /** - * Interface of any applications controlled by Selenium WebDriver API + * Interface of any application controlled by Selenium WebDriver API */ public interface IApplication { @@ -15,7 +15,7 @@ public interface IApplication { RemoteWebDriver getDriver(); /** - * @return Is the applications already running or not. + * @return Is the application already running or not. */ boolean isStarted(); diff --git a/src/test/java/tests/application/IApplicationTests.java b/src/test/java/tests/application/IApplicationTests.java index c3ded8d..9eef6e8 100644 --- a/src/test/java/tests/application/IApplicationTests.java +++ b/src/test/java/tests/application/IApplicationTests.java @@ -22,7 +22,7 @@ default void testShouldBePossibleToGetApplication() { @Test default void testShouldBePossibleToGetDriver() { - Assert.assertNotNull(getApplication().getDriver(), "should be possible get driver from the applications"); + Assert.assertNotNull(getApplication().getDriver(), "should be possible get driver from the application"); } @Test @@ -42,17 +42,17 @@ default void checkImplicitWaitSetting(int valueInSeconds) { @Test default void testShouldBePossibleToDefineIsStarted() { Assert.assertFalse(isApplicationStarted(), - "applications should not be started before getting"); + "application should not be started before getting"); IApplication application = getApplication(); Assert.assertTrue(application.isStarted(), - "applications should be started when got it from the aquality services"); + "application should be started when got it from the aquality services"); Assert.assertTrue(isApplicationStarted(), - "applications should be started when check it's state from the aquality services"); + "application should be started when check it's state from the aquality services"); application.getDriver().quit(); Assert.assertFalse(application.isStarted(), - "applications should not be started after quit"); + "application should not be started after quit"); Assert.assertFalse(isApplicationStarted(), - "applications should not be started when check it's state from the aquality services after quit"); + "application should not be started when check it's state from the aquality services after quit"); } @AfterMethod From c4d26aa70943b806dfdda644e4e87cb4cb8c4b94 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Fri, 31 Jan 2020 13:21:41 +0300 Subject: [PATCH 32/38] #6 removed using of DI in tests --- .../core/waitings/ConditionalWait.java | 2 +- .../tests/waitings/ConditionalWaitTests.java | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java index 4109319..8cebd7d 100644 --- a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -23,7 +23,7 @@ public class ConditionalWait implements IConditionalWait { private ILocalizationManager localizationManager; @Inject - private ConditionalWait(Provider applicationProvider, ITimeoutConfiguration timeoutConfiguration, ILocalizationManager localizationManager) { + public ConditionalWait(Provider applicationProvider, ITimeoutConfiguration timeoutConfiguration, ILocalizationManager localizationManager) { application = applicationProvider.get(); this.timeoutConfiguration = timeoutConfiguration; this.localizationManager = localizationManager; diff --git a/src/test/java/tests/waitings/ConditionalWaitTests.java b/src/test/java/tests/waitings/ConditionalWaitTests.java index ffae995..6b358d2 100644 --- a/src/test/java/tests/waitings/ConditionalWaitTests.java +++ b/src/test/java/tests/waitings/ConditionalWaitTests.java @@ -1,7 +1,11 @@ package tests.waitings; +import aquality.selenium.core.applications.IApplication; import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.waitings.IConditionalWait; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.waitings.ConditionalWait; +import com.google.inject.Injector; +import com.google.inject.Provider; import org.openqa.selenium.StaleElementReferenceException; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -21,17 +25,21 @@ public class ConditionalWaitTests { private static final long waitForTimeoutPolling = 150; private ThreadLocal timer = ThreadLocal.withInitial(Timer::new); private ITimeoutConfiguration timeoutConfiguration; - private IConditionalWait conditionalWait; + private Provider application; + private ConditionalWait conditionalWait; @BeforeMethod public void init() { - timeoutConfiguration = CustomAqualityServices.getServiceProvider().getInstance(ITimeoutConfiguration.class); - conditionalWait = CustomAqualityServices.getServiceProvider().getInstance(IConditionalWait.class); + Injector serviceProvider = CustomAqualityServices.getServiceProvider(); + ILocalizationManager localizationManager = serviceProvider.getInstance(ILocalizationManager.class); + application = serviceProvider.getProvider(IApplication.class); + timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); + conditionalWait = new ConditionalWait(application, timeoutConfiguration, localizationManager); } @AfterMethod public void quitApplication() { - CustomAqualityServices.getApplication().getDriver().quit(); + application.get().getDriver().quit(); } @Test @@ -78,7 +86,7 @@ public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeo assertTrue(result, "waitForTrue should return true when condition is satisfied."); assertTrue(duration < timeoutCondition, String.format("Duration '%s' should be less than timeoutCondition '%s' when condition is satisfied.", - duration, timeoutCondition)); + duration, timeoutCondition)); } @Test From 9e0d6074727417bddedd561f15794e51ce2f9ee0 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Fri, 31 Jan 2020 18:39:08 +0300 Subject: [PATCH 33/38] Merge branch 'master' into Feature/6-ConditionalWait # Conflicts: # src/main/java/aquality/selenium/core/applications/AqualityModule.java # src/main/java/aquality/selenium/core/localization/ILocalizationManager.java # src/main/java/aquality/selenium/core/localization/LocalizationManager.java # src/test/resources/TestSuite.xml updated IConditionalWait --- .../core/waitings/ConditionalWait.java | 74 +++-- .../core/waitings/IConditionalWait.java | 260 ++++++++++++++++- src/main/resources/localization/be.json | 4 +- src/main/resources/localization/en.json | 4 +- src/main/resources/localization/ru.json | 4 +- .../waitings/BaseConditionalWaitTest.java | 48 +++ .../tests/waitings/WaitForObjectTests.java | 273 ++++++++++++++++++ .../java/tests/waitings/WaitForTests.java | 96 ++++++ ...alWaitTests.java => WaitForTrueTests.java} | 112 ++++++- src/test/resources/TestSuite.xml | 2 +- 10 files changed, 817 insertions(+), 60 deletions(-) create mode 100644 src/test/java/tests/waitings/BaseConditionalWaitTest.java create mode 100644 src/test/java/tests/waitings/WaitForObjectTests.java create mode 100644 src/test/java/tests/waitings/WaitForTests.java rename src/test/java/tests/waitings/{ConditionalWaitTests.java => WaitForTrueTests.java} (66%) diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java index 5b8dbce..8f51f84 100644 --- a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -3,6 +3,7 @@ import aquality.selenium.core.applications.IApplication; import aquality.selenium.core.configurations.ITimeoutConfiguration; import aquality.selenium.core.localization.ILocalizationManager; +import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.Provider; import org.openqa.selenium.StaleElementReferenceException; @@ -30,14 +31,9 @@ public ConditionalWait(Provider applicationProvider, ITimeoutConfi } @Override - public boolean waitFor(BooleanSupplier condition, String message) { - return waitFor(condition, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), message); - } - - @Override - public boolean waitFor(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message) { + public boolean waitFor(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) { try { - waitForTrue(condition, timeoutInSeconds, pollingIntervalInMilliseconds, message); + waitForTrue(condition, timeoutInSeconds, pollingIntervalInMilliseconds, message, exceptionsToIgnore); return true; } catch (TimeoutException e) { return false; @@ -45,30 +41,28 @@ public boolean waitFor(BooleanSupplier condition, long timeoutInSeconds, long po } @Override - public void waitForTrue(BooleanSupplier condition, String message) throws TimeoutException { - waitForTrue(condition, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), message); - } - - @Override - public void waitForTrue(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message) throws TimeoutException { + public void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) throws TimeoutException { if (condition == null) { throw new IllegalArgumentException(localizationManager.getLocalizedMessage("loc.wait.condition.cant.be.null")); } + Long timeout = resolveConditionTimeout(timeoutInSeconds); + Long pollingInterval = resolvePollingInterval(pollingIntervalInMilliseconds); + String exMessage = resolveMessage(message); double startTime = getCurrentTime(); while (true) { - if (condition.getAsBoolean()) { + if (isConditionSatisfied(condition, exceptionsToIgnore)) { return; } double currentTime = getCurrentTime(); - if ((currentTime - startTime) > timeoutInSeconds) { - String exceptionMessage = String.format(localizationManager.getLocalizedMessage("loc.wait.timeout.condition"), timeoutInSeconds, message); + if ((currentTime - startTime) > timeout) { + String exceptionMessage = localizationManager.getLocalizedMessage("loc.wait.timeout.condition", timeout, exMessage); throw new TimeoutException(exceptionMessage); } try { - Thread.sleep(pollingIntervalInMilliseconds); + Thread.sleep(pollingInterval); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -76,21 +70,15 @@ public void waitForTrue(BooleanSupplier condition, long timeoutInSeconds, long p } @Override - public T waitFor(ExpectedCondition condition, String message) { - return waitFor(condition, - timeoutConfiguration.getCondition(), - timeoutConfiguration.getPollingInterval(), - message, - Collections.singleton(StaleElementReferenceException.class)); - } - - @Override - public T waitFor(ExpectedCondition condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) { + public T waitFor(ExpectedCondition condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) { application.setImplicitWaitTimeout(0, TimeUnit.SECONDS); - WebDriverWait wait = new WebDriverWait(application.getDriver(), timeOutInSeconds); - wait.pollingEvery(Duration.ofMillis(pollingIntervalInMilliseconds)); - wait.withMessage(message); - wait.ignoreAll(exceptionsToIgnore); + Long timeout = resolveConditionTimeout(timeoutInSeconds); + Long pollingInterval = resolvePollingInterval(pollingIntervalInMilliseconds); + String exMessage = resolveMessage(message); + WebDriverWait wait = new WebDriverWait(application.getDriver(), timeout); + wait.pollingEvery(Duration.ofMillis(pollingInterval)); + wait.withMessage(exMessage); + wait.ignoreAll(exceptionsToIgnore == null ? Collections.singleton(StaleElementReferenceException.class) : exceptionsToIgnore); try { return wait.until(condition); } finally { @@ -101,4 +89,28 @@ public T waitFor(ExpectedCondition condition, long timeOutInSeconds, long private double getCurrentTime() { return System.nanoTime() / Math.pow(10, 9); } + + private boolean isConditionSatisfied(BooleanSupplier condition, Collection> exceptionsToIgnore) { + try { + return condition.getAsBoolean(); + } catch (Exception e) { + if (exceptionsToIgnore == null || !exceptionsToIgnore.contains(e.getClass())) { + throw e; + } + + return false; + } + } + + private Long resolveConditionTimeout(Long timeout) { + return timeout == null ? timeoutConfiguration.getCommand() : timeout; + } + + private Long resolvePollingInterval(Long timeout) { + return timeout == null ? timeoutConfiguration.getPollingInterval() : timeout; + } + + private String resolveMessage(String message) { + return Strings.isNullOrEmpty(message) ? "" : message; + } } diff --git a/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java index a74dc04..5d84385 100644 --- a/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/IConditionalWait.java @@ -16,43 +16,211 @@ public interface IConditionalWait { * Wait for some condition within timeout. Method does not use WebDriverWait * Default values for timeouts used from configuration settings file * - * @param condition condition with boolean result (predicate) + * @param condition Condition with boolean result (predicate) + * @return true if the condition has been met during the timeout + */ + default boolean waitFor(BooleanSupplier condition) { + return waitFor(condition, null, null, null, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition Condition with boolean result (predicate) * @param message Part of error message in case of Timeout exception * @return true if the condition has been met during the timeout */ - boolean waitFor(BooleanSupplier condition, String message); + default boolean waitFor(BooleanSupplier condition, String message) { + return waitFor(condition, null, null, message, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition Condition with boolean result (predicate) + * @param exceptionsToIgnore Exceptions to ignore + * @return true if the condition has been met during the timeout + */ + default boolean waitFor(BooleanSupplier condition, Collection> exceptionsToIgnore) { + return waitFor(condition, null, null, null, exceptionsToIgnore); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition Condition with boolean result (predicate) + * @param message Part of error message in case of Timeout exception + * @param exceptionsToIgnore Exceptions to ignore + * @return true if the condition has been met during the timeout + */ + default boolean waitFor(BooleanSupplier condition, String message, Collection> exceptionsToIgnore) { + return waitFor(condition, null, null, message, exceptionsToIgnore); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition Condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval + * @return true if the condition has been met during the timeout + */ + default boolean waitFor(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds) { + return waitFor(condition, timeoutInSeconds, pollingIntervalInMilliseconds, null, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition Condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval + * @param message Part of error message in case of Timeout exception + * @return true if the condition has been met during the timeout + */ + default boolean waitFor(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message) { + return waitFor(condition, timeoutInSeconds, pollingIntervalInMilliseconds, message, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition Condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval + * @param exceptionsToIgnore Exceptions to ignore + * @return true if the condition has been met during the timeout + */ + default boolean waitFor(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, Collection> exceptionsToIgnore) { + return waitFor(condition, timeoutInSeconds, pollingIntervalInMilliseconds, null, exceptionsToIgnore); + } /** * Wait for some condition within timeout. Method does not use WebDriverWait * - * @param condition condition with boolean result (predicate) + * @param condition Condition with boolean result (predicate) * @param timeoutInSeconds Condition timeout * @param pollingIntervalInMilliseconds Condition check interval * @param message Part of error message in case of Timeout exception + * @param exceptionsToIgnore Exceptions to ignore * @return true if the condition has been met during the timeout */ - boolean waitFor(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message); + boolean waitFor(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore); /** * Wait for some condition within timeout. Method does not use WebDriverWait * Default values for timeouts used from configuration settings file * - * @param condition condition with boolean result (predicate) + * @param condition Condition with boolean result (predicate) + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + default void waitForTrue(BooleanSupplier condition) throws TimeoutException { + waitForTrue(condition, null, null, null, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition Condition with boolean result (predicate) + * @param message Part of error message in case of Timeout exception + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + default void waitForTrue(BooleanSupplier condition, String message) throws TimeoutException { + waitForTrue(condition, null, null, message, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition Condition with boolean result (predicate) + * @param exceptionsToIgnore Exceptions to ignore + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + default void waitForTrue(BooleanSupplier condition, Collection> exceptionsToIgnore) throws TimeoutException { + waitForTrue(condition, null, null, null, exceptionsToIgnore); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * Default values for timeouts used from configuration settings file + * + * @param condition Condition with boolean result (predicate) + * @param message Part of error message in case of Timeout exception + * @param exceptionsToIgnore Exceptions to ignore + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + default void waitForTrue(BooleanSupplier condition, String message, Collection> exceptionsToIgnore) throws TimeoutException { + waitForTrue(condition, null, null, message, exceptionsToIgnore); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition Condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + default void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds) throws TimeoutException { + waitForTrue(condition, timeoutInSeconds, pollingIntervalInMilliseconds, null, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition Condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval * @param message Part of error message in case of Timeout exception * @throws TimeoutException will be thrown in case if timeout is over but condition was not met */ - void waitForTrue(BooleanSupplier condition, String message) throws TimeoutException; + default void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message) throws TimeoutException { + waitForTrue(condition, timeoutInSeconds, pollingIntervalInMilliseconds, message, null); + } + + /** + * Wait for some condition within timeout. Method does not use WebDriverWait + * + * @param condition Condition with boolean result (predicate) + * @param timeoutInSeconds Condition timeout + * @param pollingIntervalInMilliseconds Condition check interval + * @param exceptionsToIgnore Exceptions to ignore + * @throws TimeoutException will be thrown in case if timeout is over but condition was not met + */ + default void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, Collection> exceptionsToIgnore) throws TimeoutException { + waitForTrue(condition, timeoutInSeconds, pollingIntervalInMilliseconds, null, exceptionsToIgnore); + } + /** * Wait for some condition within timeout. Method does not use WebDriverWait * - * @param condition condition with boolean result (predicate) + * @param condition Condition with boolean result (predicate) * @param timeoutInSeconds Condition timeout * @param pollingIntervalInMilliseconds Condition check interval * @param message Part of error message in case of Timeout exception + * @param exceptionsToIgnore Exceptions to ignore * @throws TimeoutException will be thrown in case if timeout is over but condition was not met */ - void waitForTrue(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message) throws TimeoutException; + void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) throws TimeoutException; + + /** + * Waits for function will be true or return some except false. + * Default timeout condition from settings is using. + * StaleElementReferenceException will be handled by default + * + * @param condition Function for waiting {@link Function} + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occurred + */ + default T waitFor(ExpectedCondition condition) { + return waitFor(condition, null, null, null, null); + } /** * Waits for function will be true or return some except false. @@ -64,18 +232,90 @@ public interface IConditionalWait { * @param Type of object which is waiting * @return Object which waiting for or null - is exceptions occurred */ - T waitFor(ExpectedCondition condition, String message); + default T waitFor(ExpectedCondition condition, String message) { + return waitFor(condition, null, null, message, null); + } + + /** + * Waits for function will be true or return some except false. + * Default timeout condition from settings is using. + * + * @param condition Function for waiting {@link Function} + * @param exceptionsToIgnore list of exceptions that should be ignored during waiting + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occurred + */ + default T waitFor(ExpectedCondition condition, Collection> exceptionsToIgnore) { + return waitFor(condition, null, null, null, exceptionsToIgnore); + } + + /** + * Waits for function will be true or return some except false. + * Default timeout condition from settings is using. + * + * @param condition Function for waiting {@link Function} + * @param message the message that will be added to an error in case if the condition is not matched during the timeout + * @param exceptionsToIgnore list of exceptions that should be ignored during waiting + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occurred + */ + default T waitFor(ExpectedCondition condition, String message, Collection> exceptionsToIgnore) { + return waitFor(condition, null, null, message, exceptionsToIgnore); + } /** * Waits for function will be true or return some except false. + * StaleElementReferenceException will be handled by default * * @param condition Function for waiting {@link Function} * @param timeOutInSeconds Time-out in seconds * @param pollingIntervalInMilliseconds interval in milliseconds between checks whether condition match + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occured + */ + default T waitFor(ExpectedCondition condition, Long timeOutInSeconds, Long pollingIntervalInMilliseconds) { + return waitFor(condition, timeOutInSeconds, pollingIntervalInMilliseconds, null, null); + } + + /** + * Waits for function will be true or return some except false. + * StaleElementReferenceException will be handled by default + * + * @param condition Function for waiting {@link Function} + * @param timeoutInSeconds Time-out in seconds + * @param pollingIntervalInMilliseconds interval in milliseconds between checks whether condition match + * @param message the message that will be added to an error in case if the condition is not matched during the timeout + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occured + */ + default T waitFor(ExpectedCondition condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message) { + return waitFor(condition, timeoutInSeconds, pollingIntervalInMilliseconds, message, null); + } + + /** + * Waits for function will be true or return some except false. + * + * @param condition Function for waiting {@link Function} + * @param timeoutInSeconds Time-out in seconds + * @param pollingIntervalInMilliseconds interval in milliseconds between checks whether condition match + * @param exceptionsToIgnore list of exceptions that should be ignored during waiting + * @param Type of object which is waiting + * @return Object which waiting for or null - is exceptions occured + */ + default T waitFor(ExpectedCondition condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, Collection> exceptionsToIgnore) { + return waitFor(condition, timeoutInSeconds, pollingIntervalInMilliseconds, null, exceptionsToIgnore); + } + + /** + * Waits for function will be true or return some except false. + * + * @param condition Function for waiting {@link Function} + * @param timeoutInSeconds Time-out in seconds + * @param pollingIntervalInMilliseconds interval in milliseconds between checks whether condition match * @param message the message that will be added to an error in case if the condition is not matched during the timeout * @param exceptionsToIgnore list of exceptions that should be ignored during waiting * @param Type of object which is waiting * @return Object which waiting for or null - is exceptions occured */ - T waitFor(ExpectedCondition condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore); + T waitFor(ExpectedCondition condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore); } diff --git a/src/main/resources/localization/be.json b/src/main/resources/localization/be.json index b364b8a..9557e22 100644 --- a/src/main/resources/localization/be.json +++ b/src/main/resources/localization/be.json @@ -7,5 +7,7 @@ "loc.no.elements.found.by.locator": "Не знайшлі элементаў па лакатару '%1$s'", "loc.elements.were.found.but.not.in.state": "Знайшлі элементы па лакатару '%1$s', але яны не ў жаданым стане %2$s", "loc.elements.found.but.should.not": "Не павінна быць знойдзена элементаў па лакатару '%1$s' у %2$s стане", - "loc.search.of.elements.failed": "Пошук элемента па лакатару '%1$s' прайшоў няўдала" + "loc.search.of.elements.failed": "Пошук элемента па лакатару '%1$s' прайшоў няўдала", + "loc.wait.condition.cant.be.null": "Чаканая ўмова не павінна быць null", + "loc.wait.timeout.condition": "Не атрымалася дачакацца ўмовы '%2$s' за %1$s секунд(ы)" } \ No newline at end of file diff --git a/src/main/resources/localization/en.json b/src/main/resources/localization/en.json index 0021326..9871631 100644 --- a/src/main/resources/localization/en.json +++ b/src/main/resources/localization/en.json @@ -7,5 +7,7 @@ "loc.no.elements.found.by.locator": "No elements were found by locator '%1$s'", "loc.elements.were.found.but.not.in.state": "Elements were found by locator '%1$s' but not in desired state %2$s", "loc.elements.found.but.should.not": "No elements should be found by locator '%1$s' in %2$s state", - "loc.search.of.elements.failed": "Search of element by locator '%1$s' failed" + "loc.search.of.elements.failed": "Search of element by locator '%1$s' failed", + "loc.wait.condition.cant.be.null": "Condition cannot be null", + "loc.wait.timeout.condition": "Timed out after %1$s seconds during wait for condition '%2$s'" } \ No newline at end of file diff --git a/src/main/resources/localization/ru.json b/src/main/resources/localization/ru.json index c1eba70..a36f06f 100644 --- a/src/main/resources/localization/ru.json +++ b/src/main/resources/localization/ru.json @@ -7,5 +7,7 @@ "loc.no.elements.found.by.locator": "Не удалось найти элементов по локатору '%1$s'", "loc.elements.were.found.but.not.in.state": "Удалось найти элементы по локатору '%1$s', но они не в желаемом состоянии %2$s", "loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s' в %2$s состоянии", - "loc.search.of.elements.failed": "Поиск элемента по локатору '%1$s' прошел неудачно" + "loc.search.of.elements.failed": "Поиск элемента по локатору '%1$s' прошел неудачно", + "loc.wait.condition.cant.be.null": "Ожидаемое условие не должно быть null", + "loc.wait.timeout.condition": "Не удалось дождаться ожидаемого условия '%2$s' в течении %1$s секунд(ы)" } \ No newline at end of file diff --git a/src/test/java/tests/waitings/BaseConditionalWaitTest.java b/src/test/java/tests/waitings/BaseConditionalWaitTest.java new file mode 100644 index 0000000..026e0c3 --- /dev/null +++ b/src/test/java/tests/waitings/BaseConditionalWaitTest.java @@ -0,0 +1,48 @@ +package tests.waitings; + +import aquality.selenium.core.applications.IApplication; +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.waitings.ConditionalWait; +import com.google.inject.Injector; +import com.google.inject.Provider; +import org.openqa.selenium.StaleElementReferenceException; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import utils.Timer; + +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BooleanSupplier; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +class BaseConditionalWaitTest { + + static final long waitForTimeoutCondition = 10; + static final long waitForTimeoutPolling = 150; + static final long ACCURANCY = 1; + ThreadLocal timer = ThreadLocal.withInitial(Timer::new); + ITimeoutConfiguration timeoutConfiguration; + ConditionalWait conditionalWait; + private Provider application; + + @BeforeMethod + public void init() { + Injector serviceProvider = CustomAqualityServices.getServiceProvider(); + ILocalizationManager localizationManager = serviceProvider.getInstance(ILocalizationManager.class); + application = serviceProvider.getProvider(IApplication.class); + timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); + conditionalWait = new ConditionalWait(application, timeoutConfiguration, localizationManager); + } + + @AfterMethod + public void quitApplication() { + application.get().getDriver().quit(); + } +} diff --git a/src/test/java/tests/waitings/WaitForObjectTests.java b/src/test/java/tests/waitings/WaitForObjectTests.java new file mode 100644 index 0000000..420da8a --- /dev/null +++ b/src/test/java/tests/waitings/WaitForObjectTests.java @@ -0,0 +1,273 @@ +package tests.waitings; + +import aquality.selenium.core.applications.IApplication; +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.waitings.ConditionalWait; +import com.google.inject.Injector; +import com.google.inject.Provider; +import org.openqa.selenium.StaleElementReferenceException; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tests.application.CustomAqualityServices; +import utils.Timer; + +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BooleanSupplier; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class WaitForObjectTests extends BaseConditionalWaitTest{ + + private static final long waitForTimeoutCondition = 10; + private static final long waitForTimeoutPolling = 150; + private ThreadLocal timer = ThreadLocal.withInitial(Timer::new); + private ITimeoutConfiguration timeoutConfiguration; + private Provider application; + private ConditionalWait conditionalWait; + + @BeforeMethod + public void init() { + Injector serviceProvider = CustomAqualityServices.getServiceProvider(); + ILocalizationManager localizationManager = serviceProvider.getInstance(ILocalizationManager.class); + application = serviceProvider.getProvider(IApplication.class); + timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); + conditionalWait = new ConditionalWait(application, timeoutConfiguration, localizationManager); + } + + @AfterMethod + public void quitApplication() { + application.get().getDriver().quit(); + } + + //--------- boolean WaitFor tests-------------// + @Test + public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { + checkWaitForMethodForFailedCondition( + () -> conditionalWait.waitFor(() -> false, "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testFalseShouldBeReturnedIfConditionIsNotMetAndCustomTimeoutIsOver() { + checkWaitForMethodForFailedCondition( + () -> conditionalWait.waitFor(() -> false, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + private void checkWaitForMethodForFailedCondition(BooleanSupplier waitAction, long timeout) { + timer.get().start(); + boolean result = waitAction.getAsBoolean(); + double duration = timer.get().stop(); + assertFalse(result, "waitFor should return false when condition is not satisfied."); + assertTrue(duration > timeout && duration < 2 * timeout, + String.format("Duration '%s' should be between timeout '%s' and 2*timeoutCondition when condition is not satisfied.", + duration, timeout)); + } + + @Test + public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> true, "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testTrueShouldBeReturnedIfConditionIsMetAndCustomTimeoutIsNotOver() { + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> true, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + @Test + public void testWaitForWithDefaultTimeoutsShouldCatchExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalArgumentException(""); + } + + return true; + }, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testWaitForCatchExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalArgumentException(""); + } + + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + timer.get().start(); + boolean result = waitAction.getAsBoolean(); + double duration = timer.get().stop(); + assertTrue(result, "waitFor should return true when condition is satisfied."); + assertTrue(duration < timeout, + String.format("Duration '%s' should be leas than timeoutCondition '%s'", + duration, timeout)); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNullCannotBePassedAsCondition() { + conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); + } + + //--------- boolean WaitForTrue tests-------------// + + @Test + public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() { + try { + conditionalWait.waitForTrue(() -> + { + timer.get().start(); + return false; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); + } catch (TimeoutException e) { + double duration = timer.get().stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, + String.format("Duration '%s' should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition when condition is not satisfied.", + duration, waitForTimeoutCondition)); + } + } + + private void checkWaitForTrueMethodForFailedCondition(Callable waitForTrueAction, long timeout) { + /*timer.get().start(); + try { + waitForTrueAction.call(); + } catch (TimeoutException e) { + double duration = timer.get().stop(); + assertTrue(duration > timeout && duration < 2 * timeout, + String.format("Duration '%s' should be between timeout '%s' and 2*timeout when condition is not satisfied.", + duration, timeout)); + }*/ + } + + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeoutIsNotOver() { + long timeoutCondition = timeoutConfiguration.getCondition(); + + boolean result = conditionalWait.waitFor(() -> + { + timer.get().start(); + return true; + }, "Timeout exception should not be thrown"); + double duration = timer.get().stop(); + assertTrue(result, "waitForTrue should return true when condition is satisfied."); + assertTrue(duration < timeoutCondition, + String.format("Duration '%s' should be less than timeoutCondition '%s' when condition is satisfied.", + duration, timeoutCondition)); + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOver() throws TimeoutException { + conditionalWait.waitForTrue(() -> + { + timer.get().start(); + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); + double duration = timer.get().stop(); + assertTrue(duration < waitForTimeoutCondition, + String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", + duration, waitForTimeoutCondition)); + } + + + @Test + public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaultTimeoutIsOver() { + long timeoutCondition = timeoutConfiguration.getCondition(); + try { + conditionalWait.waitFor((driver) -> + { + timer.get().start(); + return false; + }, + "Condition should be true"); + } catch (org.openqa.selenium.TimeoutException e) { + double duration = timer.get().stop(); + assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition, + String.format("Duration '%s' before throwing should be between timeoutCondition '%s' and 2*timeoutCondition ", + duration, timeoutCondition)); + } + } + + @Test + public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeoutIsOver() { + try { + conditionalWait.waitFor((driver) -> + { + timer.get().start(); + return false; + }, waitForTimeoutCondition, waitForTimeoutPolling, + "Conditional should be true", Collections.singleton(StaleElementReferenceException.class)); + + } catch (org.openqa.selenium.TimeoutException e) { + double duration = timer.get().stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, + String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", + duration, waitForTimeoutCondition)); + } + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndDefaultTimeoutIsNotOver() { + conditionalWait.waitFor((driver) -> + { + timer.get().start(); + return true; + }, + "Conditional should be true"); + double duration = timer.get().stop(); + assertTrue(duration < timeoutConfiguration.getCondition(), + String.format("Duration '%s' should be less than condition timeout '%s' when condition is satisfied.", + duration, timeoutConfiguration.getCondition())); + } + + @Test + public void testExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver() { + try { + conditionalWait.waitFor((driver) -> + { + timer.get().start(); + throw new IllegalArgumentException("I am exception"); + }, waitForTimeoutCondition, waitForTimeoutPolling, + "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); + } catch (org.openqa.selenium.TimeoutException e) { + double duration = timer.get().stop(); + assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, + String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", + duration, waitForTimeoutCondition)); + } + } + + @Test + public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOver() { + conditionalWait.waitFor((driver) -> + { + timer.get().start(); + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, + "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); + double duration = timer.get().stop(); + assertTrue(duration < waitForTimeoutCondition, + String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", + duration, waitForTimeoutCondition)); + } +} diff --git a/src/test/java/tests/waitings/WaitForTests.java b/src/test/java/tests/waitings/WaitForTests.java new file mode 100644 index 0000000..1bac694 --- /dev/null +++ b/src/test/java/tests/waitings/WaitForTests.java @@ -0,0 +1,96 @@ +package tests.waitings; + +import org.testng.annotations.Test; + +import java.util.Date; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BooleanSupplier; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class WaitForTests extends BaseConditionalWaitTest { + + @Test + public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { + checkWaitForMethodForFailedCondition( + () -> conditionalWait.waitFor(() -> false, "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testFalseShouldBeReturnedIfConditionIsNotMetAndCustomTimeoutIsOver() { + checkWaitForMethodForFailedCondition( + () -> conditionalWait.waitFor(() -> false, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + private void checkWaitForMethodForFailedCondition(BooleanSupplier waitAction, long timeout) { + Date startTime = new Date(); + boolean result = waitAction.getAsBoolean(); + long duration = (new Date().getTime() - startTime.getTime())/1000; + assertFalse(result, "waitFor should return false when condition is not satisfied."); + assertTrue(duration > timeout - ACCURANCY && duration < 2 * timeout + ACCURANCY, + String.format("Duration '%s' should be between timeout '%s' and 2*timeoutCondition when condition is not satisfied.", + duration, timeout)); + } + + @Test + public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> true, "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testTrueShouldBeReturnedIfConditionIsMetAndCustomTimeoutIsNotOver() { + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> true, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + @Test + public void testWaitForWithDefaultTimeoutsShouldCatchExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalArgumentException(""); + } + + return true; + }, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testWaitForCatchExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalArgumentException(""); + } + + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + timer.get().start(); + boolean result = waitAction.getAsBoolean(); + double duration = timer.get().stop(); + assertTrue(result, "waitFor should return true when condition is satisfied."); + assertTrue(duration < timeout, + String.format("Duration '%s' should be leas than timeoutCondition '%s'", + duration, timeout)); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNullCannotBePassedAsCondition() { + conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); + } +} diff --git a/src/test/java/tests/waitings/ConditionalWaitTests.java b/src/test/java/tests/waitings/WaitForTrueTests.java similarity index 66% rename from src/test/java/tests/waitings/ConditionalWaitTests.java rename to src/test/java/tests/waitings/WaitForTrueTests.java index 1826ac4..276ec4b 100644 --- a/src/test/java/tests/waitings/ConditionalWaitTests.java +++ b/src/test/java/tests/waitings/WaitForTrueTests.java @@ -14,13 +14,15 @@ import utils.Timer; import java.util.Collections; +import java.util.concurrent.Callable; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BooleanSupplier; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -public class ConditionalWaitTests { +public class WaitForTrueTests extends BaseConditionalWaitTest{ private static final long waitForTimeoutCondition = 10; private static final long waitForTimeoutPolling = 150; @@ -43,21 +45,92 @@ public void quitApplication() { application.get().getDriver().quit(); } + //--------- boolean WaitFor tests-------------// @Test public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { - long timeoutCondition = timeoutConfiguration.getCondition(); - boolean result = conditionalWait.waitFor(() -> - { - timer.get().start(); - return false; - }, "Condition should be true"); + checkWaitForMethodForFailedCondition( + () -> conditionalWait.waitFor(() -> false, "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testFalseShouldBeReturnedIfConditionIsNotMetAndCustomTimeoutIsOver() { + checkWaitForMethodForFailedCondition( + () -> conditionalWait.waitFor(() -> false, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + private void checkWaitForMethodForFailedCondition(BooleanSupplier waitAction, long timeout) { + timer.get().start(); + boolean result = waitAction.getAsBoolean(); double duration = timer.get().stop(); - assertFalse(result, "waitForTrue should return false when condition is not satisfied."); - assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition, - String.format("Duration '%s' should be between timeoutCondition '%s' and 2*timeoutCondition when condition is not satisfied.", - duration, timeoutCondition)); + assertFalse(result, "waitFor should return false when condition is not satisfied."); + assertTrue(duration > timeout && duration < 2 * timeout, + String.format("Duration '%s' should be between timeout '%s' and 2*timeoutCondition when condition is not satisfied.", + duration, timeout)); } + @Test + public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> true, "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testTrueShouldBeReturnedIfConditionIsMetAndCustomTimeoutIsNotOver() { + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> true, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + @Test + public void testWaitForWithDefaultTimeoutsShouldCatchExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalArgumentException(""); + } + + return true; + }, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), "Condition should be true"), + timeoutConfiguration.getCondition()); + } + + @Test + public void testWaitForCatchExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkWaitForMethodForPassedCondition( + () -> conditionalWait.waitFor(() -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalArgumentException(""); + } + + return true; + }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), + waitForTimeoutCondition); + } + + private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + timer.get().start(); + boolean result = waitAction.getAsBoolean(); + double duration = timer.get().stop(); + assertTrue(result, "waitFor should return true when condition is satisfied."); + assertTrue(duration < timeout, + String.format("Duration '%s' should be leas than timeoutCondition '%s'", + duration, timeout)); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNullCannotBePassedAsCondition() { + conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); + } + + //--------- boolean WaitForTrue tests-------------// + @Test public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() { try { @@ -74,6 +147,19 @@ public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() } } + private void checkWaitForTrueMethodForFailedCondition(Callable waitForTrueAction, long timeout) { + /*timer.get().start(); + try { + waitForTrueAction.call(); + } catch (TimeoutException e) { + double duration = timer.get().stop(); + assertTrue(duration > timeout && duration < 2 * timeout, + String.format("Duration '%s' should be between timeout '%s' and 2*timeout when condition is not satisfied.", + duration, timeout)); + }*/ + } + + @Test public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeoutIsNotOver() { long timeoutCondition = timeoutConfiguration.getCondition(); @@ -103,10 +189,6 @@ public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOv duration, waitForTimeoutCondition)); } - @Test(expectedExceptions = IllegalArgumentException.class) - public void testNullCannotBePassedAsCondition() { - conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); - } @Test public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaultTimeoutIsOver() { diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index aab0f2a..fce9bba 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -11,7 +11,7 @@ - + From 7afcfa0ca24054b359b292aba9258f86d61c96a6 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Mon, 3 Feb 2020 14:54:15 +0300 Subject: [PATCH 34/38] Merge branch 'master' into Feature/6-ConditionalWait # Conflicts: # src/main/java/aquality/selenium/core/applications/AqualityModule.java # src/main/java/aquality/selenium/core/localization/ILocalizationManager.java # src/main/java/aquality/selenium/core/localization/LocalizationManager.java # src/test/resources/TestSuite.xml updated IConditionalWait refactored tests for ConditionalWait --- .../core/waitings/ConditionalWait.java | 30 +- src/main/resources/localization/be.json | 4 +- src/main/resources/localization/en.json | 4 +- src/main/resources/localization/ru.json | 4 +- .../waitings/BaseConditionalWaitTest.java | 45 ++- .../tests/waitings/WaitForObjectTests.java | 310 +++++------------ .../java/tests/waitings/WaitForTests.java | 126 ++++--- .../java/tests/waitings/WaitForTrueTests.java | 325 ++++++------------ src/test/java/utils/TimeUtil.java | 8 - src/test/java/utils/Timer.java | 12 +- src/test/resources/TestSuite.xml | 2 + 11 files changed, 325 insertions(+), 545 deletions(-) delete mode 100644 src/test/java/utils/TimeUtil.java diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java index 8f51f84..0d0afc9 100644 --- a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -2,7 +2,6 @@ import aquality.selenium.core.applications.IApplication; import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.localization.ILocalizationManager; import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.Provider; @@ -13,21 +12,20 @@ import java.time.Duration; import java.util.Collection; import java.util.Collections; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.BooleanSupplier; public class ConditionalWait implements IConditionalWait { - private IApplication application; + private Provider applicationProvider; private ITimeoutConfiguration timeoutConfiguration; - private ILocalizationManager localizationManager; @Inject - public ConditionalWait(Provider applicationProvider, ITimeoutConfiguration timeoutConfiguration, ILocalizationManager localizationManager) { - application = applicationProvider.get(); + public ConditionalWait(Provider applicationProvider, ITimeoutConfiguration timeoutConfiguration) { + this.applicationProvider = applicationProvider; this.timeoutConfiguration = timeoutConfiguration; - this.localizationManager = localizationManager; } @Override @@ -42,22 +40,19 @@ public boolean waitFor(BooleanSupplier condition, Long timeoutInSeconds, Long po @Override public void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) throws TimeoutException { - if (condition == null) { - throw new IllegalArgumentException(localizationManager.getLocalizedMessage("loc.wait.condition.cant.be.null")); - } - + BooleanSupplier supplier = Optional.ofNullable(condition).orElseThrow(() -> new IllegalArgumentException("Condition cannot be null")); Long timeout = resolveConditionTimeout(timeoutInSeconds); Long pollingInterval = resolvePollingInterval(pollingIntervalInMilliseconds); String exMessage = resolveMessage(message); double startTime = getCurrentTime(); while (true) { - if (isConditionSatisfied(condition, exceptionsToIgnore)) { + if (isConditionSatisfied(supplier, exceptionsToIgnore)) { return; } double currentTime = getCurrentTime(); if ((currentTime - startTime) > timeout) { - String exceptionMessage = localizationManager.getLocalizedMessage("loc.wait.timeout.condition", timeout, exMessage); + String exceptionMessage = String.format("Timed out after %1$s seconds during wait for condition '%2$s'", timeout, exMessage); throw new TimeoutException(exceptionMessage); } @@ -71,18 +66,19 @@ public void waitForTrue(BooleanSupplier condition, Long timeoutInSeconds, Long p @Override public T waitFor(ExpectedCondition condition, Long timeoutInSeconds, Long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) { - application.setImplicitWaitTimeout(0, TimeUnit.SECONDS); + IApplication app = applicationProvider.get(); + app.setImplicitWaitTimeout(0, TimeUnit.SECONDS); Long timeout = resolveConditionTimeout(timeoutInSeconds); Long pollingInterval = resolvePollingInterval(pollingIntervalInMilliseconds); String exMessage = resolveMessage(message); - WebDriverWait wait = new WebDriverWait(application.getDriver(), timeout); + WebDriverWait wait = new WebDriverWait(app.getDriver(), timeout); wait.pollingEvery(Duration.ofMillis(pollingInterval)); wait.withMessage(exMessage); wait.ignoreAll(exceptionsToIgnore == null ? Collections.singleton(StaleElementReferenceException.class) : exceptionsToIgnore); try { return wait.until(condition); } finally { - application.setImplicitWaitTimeout(timeoutConfiguration.getImplicit(), TimeUnit.SECONDS); + app.setImplicitWaitTimeout(timeoutConfiguration.getImplicit(), TimeUnit.SECONDS); } } @@ -103,11 +99,11 @@ private boolean isConditionSatisfied(BooleanSupplier condition, Collection> ignoredExceptions = Collections.singleton(IllegalStateException.class); ThreadLocal timer = ThreadLocal.withInitial(Timer::new); - ITimeoutConfiguration timeoutConfiguration; - ConditionalWait conditionalWait; - private Provider application; + private Injector serviceProvider = AqualityServices.getServiceProvider(); + protected Provider application = serviceProvider.getProvider(IApplication.class); + ITimeoutConfiguration timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); + ConditionalWait conditionalWait = new ConditionalWait(application, timeoutConfiguration); - @BeforeMethod - public void init() { - Injector serviceProvider = CustomAqualityServices.getServiceProvider(); - ILocalizationManager localizationManager = serviceProvider.getInstance(ILocalizationManager.class); - application = serviceProvider.getProvider(IApplication.class); - timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); - conditionalWait = new ConditionalWait(application, timeoutConfiguration, localizationManager); + @AfterMethod + public void stopTimer(){ + timer.get().stop(); } - @AfterMethod - public void quitApplication() { - application.get().getDriver().quit(); + BooleanSupplier throwNewException(AtomicBoolean atomicBoolean) { + return () -> { + if (atomicBoolean.get()) { + atomicBoolean.set(false); + throw new IllegalStateException(""); + } + + return true; + }; } } diff --git a/src/test/java/tests/waitings/WaitForObjectTests.java b/src/test/java/tests/waitings/WaitForObjectTests.java index 420da8a..07f9f88 100644 --- a/src/test/java/tests/waitings/WaitForObjectTests.java +++ b/src/test/java/tests/waitings/WaitForObjectTests.java @@ -1,17 +1,10 @@ package tests.waitings; -import aquality.selenium.core.applications.IApplication; -import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.localization.ILocalizationManager; -import aquality.selenium.core.waitings.ConditionalWait; -import com.google.inject.Injector; -import com.google.inject.Provider; -import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.support.ui.ExpectedCondition; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import tests.application.CustomAqualityServices; -import utils.Timer; import java.util.Collections; import java.util.concurrent.Callable; @@ -19,255 +12,138 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BooleanSupplier; -import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; -public class WaitForObjectTests extends BaseConditionalWaitTest{ +public class WaitForObjectTests extends BaseConditionalWaitTest { - private static final long waitForTimeoutCondition = 10; - private static final long waitForTimeoutPolling = 150; - private ThreadLocal timer = ThreadLocal.withInitial(Timer::new); - private ITimeoutConfiguration timeoutConfiguration; - private Provider application; - private ConditionalWait conditionalWait; + private static final String RESULT_STRING = "result"; @BeforeMethod - public void init() { - Injector serviceProvider = CustomAqualityServices.getServiceProvider(); - ILocalizationManager localizationManager = serviceProvider.getInstance(ILocalizationManager.class); - application = serviceProvider.getProvider(IApplication.class); - timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); - conditionalWait = new ConditionalWait(application, timeoutConfiguration, localizationManager); + public void startApp() { + application.get().getDriver(); } @AfterMethod - public void quitApplication() { - application.get().getDriver().quit(); - } - - //--------- boolean WaitFor tests-------------// - @Test - public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { - checkWaitForMethodForFailedCondition( - () -> conditionalWait.waitFor(() -> false, "Condition should be true"), - timeoutConfiguration.getCondition()); - } - - @Test - public void testFalseShouldBeReturnedIfConditionIsNotMetAndCustomTimeoutIsOver() { - checkWaitForMethodForFailedCondition( - () -> conditionalWait.waitFor(() -> false, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); - } - - private void checkWaitForMethodForFailedCondition(BooleanSupplier waitAction, long timeout) { - timer.get().start(); - boolean result = waitAction.getAsBoolean(); - double duration = timer.get().stop(); - assertFalse(result, "waitFor should return false when condition is not satisfied."); - assertTrue(duration > timeout && duration < 2 * timeout, - String.format("Duration '%s' should be between timeout '%s' and 2*timeoutCondition when condition is not satisfied.", - duration, timeout)); - } - - @Test - public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> true, "Condition should be true"), - timeoutConfiguration.getCondition()); - } - - @Test - public void testTrueShouldBeReturnedIfConditionIsMetAndCustomTimeoutIsNotOver() { - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> true, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); - } - - @Test - public void testWaitForWithDefaultTimeoutsShouldCatchExceptions() { - AtomicBoolean atomicBoolean = new AtomicBoolean(true); - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> { - if (atomicBoolean.get()) { - atomicBoolean.set(false); - throw new IllegalArgumentException(""); - } - - return true; - }, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), "Condition should be true"), - timeoutConfiguration.getCondition()); + public void quit() { + if (application.get().isStarted()) { + application.get().getDriver().quit(); + } } - @Test - public void testWaitForCatchExceptions() { - AtomicBoolean atomicBoolean = new AtomicBoolean(true); - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> { - if (atomicBoolean.get()) { - atomicBoolean.set(false); - throw new IllegalArgumentException(""); - } - - return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + @DataProvider(name = "failWaitForAction", parallel = true) + public Object[][] successWaitForAction1() { + return getDataProvider((app) -> false); } - private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + @Test(dataProvider = "successWaitForAction") + public void testShouldThrowTimeoutExceptionIfConditionIsNotMetAndTimeoutIsOver(Callable failedAction, long timeout) throws Exception { timer.get().start(); - boolean result = waitAction.getAsBoolean(); - double duration = timer.get().stop(); - assertTrue(result, "waitFor should return true when condition is satisfied."); - assertTrue(duration < timeout, - String.format("Duration '%s' should be leas than timeoutCondition '%s'", - duration, timeout)); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void testNullCannotBePassedAsCondition() { - conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); - } - - //--------- boolean WaitForTrue tests-------------// - - @Test - public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() { try { - conditionalWait.waitForTrue(() -> - { - timer.get().start(); - return false; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); + failedAction.call(); } catch (TimeoutException e) { double duration = timer.get().stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, - String.format("Duration '%s' should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition when condition is not satisfied.", - duration, waitForTimeoutCondition)); + long interval = 2 * timeout + accuracy; + assertTrue(duration >= timeout && duration < interval, + String.format("Duration '%s' should be between '%s' and '%s' (timeout and (2*timeout + accuracy)) when condition is not satisfied. ", + duration, timeout, interval)); } } - private void checkWaitForTrueMethodForFailedCondition(Callable waitForTrueAction, long timeout) { - /*timer.get().start(); - try { - waitForTrueAction.call(); - } catch (TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > timeout && duration < 2 * timeout, - String.format("Duration '%s' should be between timeout '%s' and 2*timeout when condition is not satisfied.", - duration, timeout)); - }*/ + @DataProvider(name = "successWaitForAction", parallel = true) + public Object[][] successWaitForAction() { + return getDataProvider((app) -> RESULT_STRING); } - - @Test - public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeoutIsNotOver() { - long timeoutCondition = timeoutConfiguration.getCondition(); - - boolean result = conditionalWait.waitFor(() -> - { - timer.get().start(); - return true; - }, "Timeout exception should not be thrown"); + @Test(dataProvider = "successWaitForAction") + public void testShouldReturnAnObjectIfConditionIsMetAndTimeoutIsNotOver(Callable successAction, long timeout) throws Exception { + timer.get().start(); + String result = successAction.call(); double duration = timer.get().stop(); - assertTrue(result, "waitForTrue should return true when condition is satisfied."); - assertTrue(duration < timeoutCondition, - String.format("Duration '%s' should be less than timeoutCondition '%s' when condition is satisfied.", - duration, timeoutCondition)); + assertTrue(duration <= timeout, + String.format("Duration '%s' should be less than accuracyTimeout '%s'", + duration, timeout)); + assertEquals(result, RESULT_STRING, "Method should return correct object"); } - @Test - public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOver() throws TimeoutException { - conditionalWait.waitForTrue(() -> - { - timer.get().start(); - return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); - double duration = timer.get().stop(); - assertTrue(duration < waitForTimeoutCondition, - String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", - duration, waitForTimeoutCondition)); + @DataProvider(name = "throwWaitForAction", parallel = true) + public Object[][] throwWaitForAction() { + return getDataProvider((app) -> { + throw new IllegalArgumentException("I am exception"); + }); } - - @Test - public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaultTimeoutIsOver() { - long timeoutCondition = timeoutConfiguration.getCondition(); + @Test(dataProvider = "throwWaitForAction") + public void testShouldThrowException(Callable throwAction, long timeout) throws Exception { try { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return false; - }, - "Condition should be true"); - } catch (org.openqa.selenium.TimeoutException e) { + timer.get().start(); + throwAction.call(); + } catch (IllegalArgumentException e) { double duration = timer.get().stop(); - assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition, - String.format("Duration '%s' before throwing should be between timeoutCondition '%s' and 2*timeoutCondition ", - duration, timeoutCondition)); + assertTrue(duration <= timeout, + String.format("Duration '%s' should be less than accuracyTimeout '%s'", + duration, timeout)); + assertEquals(e.getMessage(), "I am exception", "It should be custom exception"); } } @Test - public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeoutIsOver() { - try { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return false; - }, waitForTimeoutCondition, waitForTimeoutPolling, - "Conditional should be true", Collections.singleton(StaleElementReferenceException.class)); - - } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, - String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", - duration, waitForTimeoutCondition)); - } + public void testShouldIgnoreExceptionForWaitingWithoutCustomParameters() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + BooleanSupplier actionWithExceptions = () -> conditionalWait.waitFor((driver) -> throwNewException(atomicBoolean).getAsBoolean(), ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithExceptions, timeoutConfiguration.getCondition()); } @Test - public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndDefaultTimeoutIsNotOver() { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return true; - }, - "Conditional should be true"); - double duration = timer.get().stop(); - assertTrue(duration < timeoutConfiguration.getCondition(), - String.format("Duration '%s' should be less than condition timeout '%s' when condition is satisfied.", - duration, timeoutConfiguration.getCondition())); + public void testShouldIgnoreExceptionForWaitingWithDefaultTimeout() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + BooleanSupplier actionWithMessageAndExceptions = () -> conditionalWait.waitFor((driver) -> throwNewException(atomicBoolean).getAsBoolean(), "Condition should be true", ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithMessageAndExceptions, timeoutConfiguration.getCondition()); } @Test - public void testExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver() { - try { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - throw new IllegalArgumentException("I am exception"); - }, waitForTimeoutCondition, waitForTimeoutPolling, - "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); - } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, - String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", - duration, waitForTimeoutCondition)); - } + public void testShouldIgnoreExceptionWaitingWithCustomTimeoutAndExceptions() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + BooleanSupplier actionWithAllParameters = () -> conditionalWait.waitFor((driver) -> throwNewException(atomicBoolean).getAsBoolean(), waitForTimeoutCondition, waitForTimeoutPolling, ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithAllParameters, waitForTimeoutCondition); } @Test - public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOver() { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, - "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); + public void testShouldIgnoreExceptionWaitingWithCustomTimeout() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + BooleanSupplier actionWithAllParameters = () -> conditionalWait.waitFor((driver) -> throwNewException(atomicBoolean).getAsBoolean(), waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true", ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithAllParameters, waitForTimeoutCondition); + } + + private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + long accuracyTimeout = timeout + accuracy; + timer.get().start(); + boolean result = waitAction.getAsBoolean(); double duration = timer.get().stop(); - assertTrue(duration < waitForTimeoutCondition, - String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", - duration, waitForTimeoutCondition)); + assertTrue(result, "waitFor should return true when condition is satisfied."); + assertTrue(duration <= accuracyTimeout, + String.format("Duration '%s' should be less than accuracyTimeout '%s'", + duration, accuracyTimeout)); + } + + private Object[][] getDataProvider(ExpectedCondition action) { + Callable onlyAction = () -> conditionalWait.waitFor(action); + Callable actionWithMessage = () -> conditionalWait.waitFor(action, "Condition should be true"); + Callable actionWithExceptions = () -> conditionalWait.waitFor(action, Collections.emptyList()); + Callable actionWithMessageAndExceptions = () -> conditionalWait.waitFor(action, "Condition should be true", Collections.emptyList()); + Callable actionWithCustomTimeouts = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling); + Callable actionWithCustomTimeoutsAndMessage = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); + Callable actionWithCustomTimeoutsAndExceptions = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling, Collections.emptyList()); + Callable actionWithAllParameters = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true", Collections.emptyList()); + return new Object[][]{ + {onlyAction, timeoutConfiguration.getCondition()}, + {actionWithMessage, timeoutConfiguration.getCondition()}, + {actionWithExceptions, timeoutConfiguration.getCondition()}, + {actionWithMessageAndExceptions, timeoutConfiguration.getCondition()}, + {actionWithCustomTimeouts, waitForTimeoutCondition}, + {actionWithCustomTimeoutsAndMessage, waitForTimeoutCondition}, + {actionWithCustomTimeoutsAndExceptions, waitForTimeoutCondition}, + {actionWithAllParameters, waitForTimeoutCondition}, + }; } } diff --git a/src/test/java/tests/waitings/WaitForTests.java b/src/test/java/tests/waitings/WaitForTests.java index 1bac694..b8ded4d 100644 --- a/src/test/java/tests/waitings/WaitForTests.java +++ b/src/test/java/tests/waitings/WaitForTests.java @@ -1,8 +1,10 @@ package tests.waitings; +import org.openqa.selenium.StaleElementReferenceException; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.util.Date; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BooleanSupplier; @@ -11,86 +13,108 @@ public class WaitForTests extends BaseConditionalWaitTest { - @Test - public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { - checkWaitForMethodForFailedCondition( - () -> conditionalWait.waitFor(() -> false, "Condition should be true"), - timeoutConfiguration.getCondition()); - } - - @Test - public void testFalseShouldBeReturnedIfConditionIsNotMetAndCustomTimeoutIsOver() { - checkWaitForMethodForFailedCondition( - () -> conditionalWait.waitFor(() -> false, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + @DataProvider(name = "falseWaitForAction", parallel = true) + public Object[][] falseWaitForAction() { + return getDataProvider(() -> false); } - private void checkWaitForMethodForFailedCondition(BooleanSupplier waitAction, long timeout) { + @Test(dataProvider = "falseWaitForAction") + public void testFalseShouldBeReturnedIfConditionIsNotMetAndTimeoutIsOver(BooleanSupplier waitAction, long timeout) { Date startTime = new Date(); boolean result = waitAction.getAsBoolean(); - long duration = (new Date().getTime() - startTime.getTime())/1000; + long duration = (new Date().getTime() - startTime.getTime()) / 1000; + long interval = 2 * timeout + accuracy; assertFalse(result, "waitFor should return false when condition is not satisfied."); - assertTrue(duration > timeout - ACCURANCY && duration < 2 * timeout + ACCURANCY, - String.format("Duration '%s' should be between timeout '%s' and 2*timeoutCondition when condition is not satisfied.", - duration, timeout)); + assertTrue(duration >= timeout && duration < interval, + String.format("Duration '%s' should be between '%s' and '%s' (timeout and (2*timeout + accuracy)) when condition is not satisfied. ", + duration, timeout, interval)); + } + + @DataProvider(name = "trueWaitForAction", parallel = true) + public Object[][] trueWaitForAction() { + return getDataProvider(() -> true); + } + + @Test(dataProvider = "trueWaitForAction") + public void testTrueShouldBeReturnedIfConditionIsMetAndTimeoutIsNotOver(BooleanSupplier waitAction, long timeout) { + checkWaitForMethodForPassedCondition(waitAction, timeout); } @Test - public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> true, "Condition should be true"), - timeoutConfiguration.getCondition()); + public void testShouldIgnoreExceptionForWaitingWithoutCustomParameters() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + BooleanSupplier actionWithExceptions = () -> conditionalWait.waitFor(throwNewException(atomicBoolean), ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithExceptions, timeoutConfiguration.getCondition()); } @Test - public void testTrueShouldBeReturnedIfConditionIsMetAndCustomTimeoutIsNotOver() { - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> true, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + public void testShouldIgnoreExceptionForWaitingWithDefaultTimeout() { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + BooleanSupplier actionWithMessageAndExceptions = () -> conditionalWait.waitFor(throwNewException(atomicBoolean), "Condition should be true", ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithMessageAndExceptions, timeoutConfiguration.getCondition()); } @Test - public void testWaitForWithDefaultTimeoutsShouldCatchExceptions() { + public void testShouldIgnoreExceptionWaitingWithCustomTimeoutAndException() { AtomicBoolean atomicBoolean = new AtomicBoolean(true); - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> { - if (atomicBoolean.get()) { - atomicBoolean.set(false); - throw new IllegalArgumentException(""); - } - - return true; - }, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), "Condition should be true"), - timeoutConfiguration.getCondition()); + BooleanSupplier actionWithAllParameters = () -> conditionalWait.waitFor(throwNewException(atomicBoolean), waitForTimeoutCondition, waitForTimeoutPolling, ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithAllParameters, waitForTimeoutCondition); } @Test - public void testWaitForCatchExceptions() { + public void testShouldIgnoreExceptionWaitingWithCustomTimeout() { AtomicBoolean atomicBoolean = new AtomicBoolean(true); - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> { - if (atomicBoolean.get()) { - atomicBoolean.set(false); - throw new IllegalArgumentException(""); - } - - return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + BooleanSupplier actionWithAllParameters = () -> conditionalWait.waitFor(throwNewException(atomicBoolean), waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true", ignoredExceptions); + checkWaitForMethodForPassedCondition(actionWithAllParameters, waitForTimeoutCondition); } private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + long accuracyTimeout = timeout + accuracy; timer.get().start(); boolean result = waitAction.getAsBoolean(); double duration = timer.get().stop(); assertTrue(result, "waitFor should return true when condition is satisfied."); - assertTrue(duration < timeout, - String.format("Duration '%s' should be leas than timeoutCondition '%s'", - duration, timeout)); + assertTrue(duration <= timeout, + String.format("Duration '%s' should be less than accuracyTimeout '%s'", + duration, accuracyTimeout)); + } + + @DataProvider(name = "throwExceptionAction", parallel = true) + public Object[][] throwExceptionAction() { + BooleanSupplier throwEx = () -> { + throw new StaleElementReferenceException(""); + }; + return getDataProvider(throwEx); + } + + @Test(dataProvider = "throwExceptionAction", expectedExceptions = StaleElementReferenceException.class) + public void testShouldThrowException(BooleanSupplier waitAction, long timeout) { + waitAction.getAsBoolean(); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullCannotBePassedAsCondition() { conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); } + + private Object[][] getDataProvider(BooleanSupplier action) { + BooleanSupplier onlyAction = () -> conditionalWait.waitFor(action); + BooleanSupplier actionWithMessage = () -> conditionalWait.waitFor(action, "Condition should be true"); + BooleanSupplier actionWithExceptions = () -> conditionalWait.waitFor(action, Collections.emptyList()); + BooleanSupplier actionWithMessageAndExceptions = () -> conditionalWait.waitFor(action, "Condition should be true", Collections.emptyList()); + BooleanSupplier actionWithCustomTimeouts = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling); + BooleanSupplier actionWithCustomTimeoutsAndMessage = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); + BooleanSupplier actionWithCustomTimeoutsAndExceptions = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling, Collections.emptyList()); + BooleanSupplier actionWithAllParameters = () -> conditionalWait.waitFor(action, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true", Collections.emptyList()); + return new Object[][]{ + {onlyAction, timeoutConfiguration.getCondition()}, + {actionWithMessage, timeoutConfiguration.getCondition()}, + {actionWithExceptions, timeoutConfiguration.getCondition()}, + {actionWithMessageAndExceptions, timeoutConfiguration.getCondition()}, + {actionWithCustomTimeouts, waitForTimeoutCondition}, + {actionWithCustomTimeoutsAndMessage, waitForTimeoutCondition}, + {actionWithCustomTimeoutsAndExceptions, waitForTimeoutCondition}, + {actionWithAllParameters, waitForTimeoutCondition}, + }; + } } diff --git a/src/test/java/tests/waitings/WaitForTrueTests.java b/src/test/java/tests/waitings/WaitForTrueTests.java index 276ec4b..f3bf3f0 100644 --- a/src/test/java/tests/waitings/WaitForTrueTests.java +++ b/src/test/java/tests/waitings/WaitForTrueTests.java @@ -1,17 +1,8 @@ package tests.waitings; -import aquality.selenium.core.applications.IApplication; -import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.localization.ILocalizationManager; -import aquality.selenium.core.waitings.ConditionalWait; -import com.google.inject.Injector; -import com.google.inject.Provider; import org.openqa.selenium.StaleElementReferenceException; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import tests.application.CustomAqualityServices; -import utils.Timer; import java.util.Collections; import java.util.concurrent.Callable; @@ -19,255 +10,163 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BooleanSupplier; -import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -public class WaitForTrueTests extends BaseConditionalWaitTest{ +public class WaitForTrueTests extends BaseConditionalWaitTest { - private static final long waitForTimeoutCondition = 10; - private static final long waitForTimeoutPolling = 150; - private ThreadLocal timer = ThreadLocal.withInitial(Timer::new); - private ITimeoutConfiguration timeoutConfiguration; - private Provider application; - private ConditionalWait conditionalWait; + @DataProvider(name = "falseWaitForTrueAction", parallel = true) + public Object[][] falseWaitForAction() { + return getDataProvider(() -> false); + } - @BeforeMethod - public void init() { - Injector serviceProvider = CustomAqualityServices.getServiceProvider(); - ILocalizationManager localizationManager = serviceProvider.getInstance(ILocalizationManager.class); - application = serviceProvider.getProvider(IApplication.class); - timeoutConfiguration = serviceProvider.getInstance(ITimeoutConfiguration.class); - conditionalWait = new ConditionalWait(application, timeoutConfiguration, localizationManager); + @Test(dataProvider = "falseWaitForTrueAction") + public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver(Callable waitForTrueAction, long timeout) throws Exception { + timer.get().start(); + try { + waitForTrueAction.call(); + } catch (TimeoutException e) { + double duration = timer.get().stop(); + long interval = 2 * timeout + accuracy; + assertTrue(duration >= timeout && duration < interval, + String.format("Duration '%s' should be between '%s' and '%s' (timeout and (2*timeout + accuracy)) when condition is not satisfied.", + duration, timeout, interval)); + } } - @AfterMethod - public void quitApplication() { - application.get().getDriver().quit(); + @DataProvider(name = "successWaitForAction", parallel = true) + public Object[][] successWaitForAction() { + return getDataProvider(() -> true); } - //--------- boolean WaitFor tests-------------// - @Test - public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { - checkWaitForMethodForFailedCondition( - () -> conditionalWait.waitFor(() -> false, "Condition should be true"), - timeoutConfiguration.getCondition()); + @Test(dataProvider = "successWaitForAction") + public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndTimeoutIsNotOver(Callable waitForTrueAction, long timeout) throws Exception { + timer.get().start(); + waitForTrueAction.call(); + double duration = timer.get().stop(); + assertTrue(duration < timeout, + String.format("Duration '%s' should be less than timeout '%s' when condition is satisfied.", + duration, timeout)); } - @Test - public void testFalseShouldBeReturnedIfConditionIsNotMetAndCustomTimeoutIsOver() { - checkWaitForMethodForFailedCondition( - () -> conditionalWait.waitFor(() -> false, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + @DataProvider(name = "throwExceptionAction", parallel = true) + public Object[][] throwExceptionAction() { + BooleanSupplier throwEx = () -> { + throw new StaleElementReferenceException(""); + }; + return getDataProvider(throwEx); } - private void checkWaitForMethodForFailedCondition(BooleanSupplier waitAction, long timeout) { + @Test(dataProvider = "throwExceptionAction", expectedExceptions = StaleElementReferenceException.class) + public void testCustomExceptionShouldBeThrown(Callable waitForTrueAction, long timeout) throws Exception { timer.get().start(); - boolean result = waitAction.getAsBoolean(); + waitForTrueAction.call(); double duration = timer.get().stop(); - assertFalse(result, "waitFor should return false when condition is not satisfied."); - assertTrue(duration > timeout && duration < 2 * timeout, - String.format("Duration '%s' should be between timeout '%s' and 2*timeoutCondition when condition is not satisfied.", + assertTrue(duration < timeout, + String.format("Duration '%s' should be less than timeout '%s' when condition is satisfied.", duration, timeout)); } - @Test - public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> true, "Condition should be true"), - timeoutConfiguration.getCondition()); + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNullCannotBePassedAsCondition() throws TimeoutException { + conditionalWait.waitForTrue(null, "Condition should not be null"); } @Test - public void testTrueShouldBeReturnedIfConditionIsMetAndCustomTimeoutIsNotOver() { - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> true, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + public void testCustomExceptionShouldBeIgnoredWithoutCustomParameters() throws Exception { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkExceptionIsIgnored(() -> { + conditionalWait.waitForTrue(throwNewException(atomicBoolean), ignoredExceptions); + return true; + }, timeoutConfiguration.getCondition()); } @Test - public void testWaitForWithDefaultTimeoutsShouldCatchExceptions() { + public void testCustomExceptionShouldBeIgnoredWithDefaultTimeout() throws Exception { AtomicBoolean atomicBoolean = new AtomicBoolean(true); - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> { - if (atomicBoolean.get()) { - atomicBoolean.set(false); - throw new IllegalArgumentException(""); - } - - return true; - }, timeoutConfiguration.getCondition(), timeoutConfiguration.getPollingInterval(), "Condition should be true"), - timeoutConfiguration.getCondition()); + checkExceptionIsIgnored(() -> { + conditionalWait.waitForTrue(throwNewException(atomicBoolean), "Condition should be true", ignoredExceptions); + return true; + }, timeoutConfiguration.getCondition()); } @Test - public void testWaitForCatchExceptions() { + public void testCustomExceptionShouldBeIgnoredWithCustomTimeoutAndException() throws Exception { AtomicBoolean atomicBoolean = new AtomicBoolean(true); - checkWaitForMethodForPassedCondition( - () -> conditionalWait.waitFor(() -> { - if (atomicBoolean.get()) { - atomicBoolean.set(false); - throw new IllegalArgumentException(""); - } + checkExceptionIsIgnored(() -> { + conditionalWait.waitForTrue(throwNewException(atomicBoolean), waitForTimeoutCondition, waitForTimeoutPolling, ignoredExceptions); + return true; + }, waitForTimeoutCondition); + } - return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"), - waitForTimeoutCondition); + @Test + public void testCustomExceptionShouldBeIgnoredWithCustomTimeout() throws Exception { + AtomicBoolean atomicBoolean = new AtomicBoolean(true); + checkExceptionIsIgnored(() -> { + conditionalWait.waitForTrue(throwNewException(atomicBoolean), waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true", ignoredExceptions); + return true; + }, waitForTimeoutCondition); } - private void checkWaitForMethodForPassedCondition(BooleanSupplier waitAction, long timeout) { + private void checkExceptionIsIgnored(Callable waitForTrueAction, long timeout) throws Exception { timer.get().start(); - boolean result = waitAction.getAsBoolean(); + waitForTrueAction.call(); double duration = timer.get().stop(); - assertTrue(result, "waitFor should return true when condition is satisfied."); assertTrue(duration < timeout, - String.format("Duration '%s' should be leas than timeoutCondition '%s'", + String.format("Duration '%s' should be less than timeout '%s' when condition is satisfied.", duration, timeout)); } - @Test(expectedExceptions = IllegalArgumentException.class) - public void testNullCannotBePassedAsCondition() { - conditionalWait.waitFor((BooleanSupplier) null, "Condition should not be null"); - } - - //--------- boolean WaitForTrue tests-------------// - - @Test - public void testTimeoutExceptionShouldBeThrownIfConditionIsMetAndTimeoutIsOver() { - try { - conditionalWait.waitForTrue(() -> - { - timer.get().start(); - return false; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); - } catch (TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, - String.format("Duration '%s' should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition when condition is not satisfied.", - duration, waitForTimeoutCondition)); - } - } - - private void checkWaitForTrueMethodForFailedCondition(Callable waitForTrueAction, long timeout) { - /*timer.get().start(); - try { - waitForTrueAction.call(); - } catch (TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > timeout && duration < 2 * timeout, - String.format("Duration '%s' should be between timeout '%s' and 2*timeout when condition is not satisfied.", - duration, timeout)); - }*/ - } - - - @Test - public void testTimeoutExceptionShouldNotBeThrownIfConditionIsMetAndDefaultTimeoutIsNotOver() { - long timeoutCondition = timeoutConfiguration.getCondition(); + private Object[][] getDataProvider(BooleanSupplier action) { - boolean result = conditionalWait.waitFor(() -> - { - timer.get().start(); + Callable onlyAction = () -> { + conditionalWait.waitForTrue(action); return true; - }, "Timeout exception should not be thrown"); - double duration = timer.get().stop(); - assertTrue(result, "waitForTrue should return true when condition is satisfied."); - assertTrue(duration < timeoutCondition, - String.format("Duration '%s' should be less than timeoutCondition '%s' when condition is satisfied.", - duration, timeoutCondition)); - } + }; - @Test - public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOver() throws TimeoutException { - conditionalWait.waitForTrue(() -> - { - timer.get().start(); + Callable actionWithMessage = () -> { + conditionalWait.waitForTrue(action, "Condition should be true"); return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); - double duration = timer.get().stop(); - assertTrue(duration < waitForTimeoutCondition, - String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", - duration, waitForTimeoutCondition)); - } - + }; - @Test - public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaultTimeoutIsOver() { - long timeoutCondition = timeoutConfiguration.getCondition(); - try { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return false; - }, - "Condition should be true"); - } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > timeoutCondition && duration < 2 * timeoutCondition, - String.format("Duration '%s' before throwing should be between timeoutCondition '%s' and 2*timeoutCondition ", - duration, timeoutCondition)); - } - } + Callable actionWithExceptions = () -> { + conditionalWait.waitForTrue(action, Collections.emptyList()); + return true; + }; - @Test - public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeoutIsOver() { - try { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return false; - }, waitForTimeoutCondition, waitForTimeoutPolling, - "Conditional should be true", Collections.singleton(StaleElementReferenceException.class)); + Callable actionWithMessageAndExceptions = () -> { + conditionalWait.waitFor(action, "Condition should be true", Collections.emptyList()); + return true; + }; - } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, - String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", - duration, waitForTimeoutCondition)); - } - } + Callable actionWithCustomTimeouts = () -> { + conditionalWait.waitForTrue(action, waitForTimeoutCondition, waitForTimeoutPolling); + return true; + }; - @Test - public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndDefaultTimeoutIsNotOver() { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return true; - }, - "Conditional should be true"); - double duration = timer.get().stop(); - assertTrue(duration < timeoutConfiguration.getCondition(), - String.format("Duration '%s' should be less than condition timeout '%s' when condition is satisfied.", - duration, timeoutConfiguration.getCondition())); - } + Callable actionWithCustomTimeoutsAndMessage = () -> { + conditionalWait.waitForTrue(action, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true"); + return true; + }; - @Test - public void testExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver() { - try { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - throw new IllegalArgumentException("I am exception"); - }, waitForTimeoutCondition, waitForTimeoutPolling, - "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); - } catch (org.openqa.selenium.TimeoutException e) { - double duration = timer.get().stop(); - assertTrue(duration > waitForTimeoutCondition && duration < 2 * waitForTimeoutCondition, - String.format("Duration '%s' before throwing should be between waitForTimeoutCondition '%s' and 2*waitForTimeoutCondition", - duration, waitForTimeoutCondition)); - } - } + Callable actionWithCustomTimeoutsAndException = () -> { + conditionalWait.waitForTrue(action, waitForTimeoutCondition, waitForTimeoutPolling, Collections.emptyList()); + return true; + }; - @Test - public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOver() { - conditionalWait.waitFor((driver) -> - { - timer.get().start(); - return true; - }, waitForTimeoutCondition, waitForTimeoutPolling, - "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); - double duration = timer.get().stop(); - assertTrue(duration < waitForTimeoutCondition, - String.format("Duration '%s' should be less than waitForTimeoutCondition '%s' when condition is satisfied.", - duration, waitForTimeoutCondition)); + Callable actionWithAllParameters = () -> { + conditionalWait.waitForTrue(action, waitForTimeoutCondition, waitForTimeoutPolling, "Condition should be true", Collections.emptyList()); + return true; + }; + + return new Object[][]{ + {onlyAction, timeoutConfiguration.getCondition()}, + {actionWithMessage, timeoutConfiguration.getCondition()}, + {actionWithExceptions, timeoutConfiguration.getCondition()}, + {actionWithMessageAndExceptions, timeoutConfiguration.getCondition()}, + {actionWithCustomTimeouts, waitForTimeoutCondition}, + {actionWithCustomTimeoutsAndMessage, waitForTimeoutCondition}, + {actionWithCustomTimeoutsAndException, waitForTimeoutCondition}, + {actionWithAllParameters, waitForTimeoutCondition}, + }; } } diff --git a/src/test/java/utils/TimeUtil.java b/src/test/java/utils/TimeUtil.java deleted file mode 100644 index 76fc87a..0000000 --- a/src/test/java/utils/TimeUtil.java +++ /dev/null @@ -1,8 +0,0 @@ -package utils; - -public class TimeUtil { - - public static double getCurrentTimeInSeconds() { - return System.nanoTime() / Math.pow(10, 9); - } -} diff --git a/src/test/java/utils/Timer.java b/src/test/java/utils/Timer.java index 42c0f56..01c5095 100644 --- a/src/test/java/utils/Timer.java +++ b/src/test/java/utils/Timer.java @@ -1,17 +1,19 @@ package utils; -import static utils.TimeUtil.*; - public class Timer { private double startTime; - public void start(){ - if(startTime == 0){ + public void start() { + if (startTime == 0) { startTime = getCurrentTimeInSeconds(); } } - public double stop(){ + public double stop() { return getCurrentTimeInSeconds() - startTime; } + + private static double getCurrentTimeInSeconds() { + return System.nanoTime() / Math.pow(10, 9); + } } \ No newline at end of file diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index fce9bba..134fff2 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -12,6 +12,8 @@ + + From 7452a3e011981ff3bee40f6f40239398c3b1d2b0 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Mon, 3 Feb 2020 15:19:06 +0300 Subject: [PATCH 35/38] small fix --- .../java/aquality/selenium/core/waitings/ConditionalWait.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java index 0d0afc9..e5a2f0c 100644 --- a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -19,8 +19,8 @@ public class ConditionalWait implements IConditionalWait { - private Provider applicationProvider; - private ITimeoutConfiguration timeoutConfiguration; + private final Provider applicationProvider; + private final ITimeoutConfiguration timeoutConfiguration; @Inject public ConditionalWait(Provider applicationProvider, ITimeoutConfiguration timeoutConfiguration) { From 991d152205978ac48506cc31d109c9806f0b6137 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Mon, 3 Feb 2020 18:11:22 +0300 Subject: [PATCH 36/38] merge with master --- .../aquality/selenium/core/applications/AqualityModule.java | 3 +-- .../java/tests/configurations/EnvConfigurationTests.java | 5 ----- .../java/tests/configurations/ProfileConfigurationTests.java | 4 +--- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/aquality/selenium/core/applications/AqualityModule.java b/src/main/java/aquality/selenium/core/applications/AqualityModule.java index 6a91fb4..45dd9d0 100644 --- a/src/main/java/aquality/selenium/core/applications/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityModule.java @@ -18,8 +18,7 @@ * Describes all dependencies which is registered for the project. */ public class AqualityModule extends AbstractModule - implements ILocalizationModule, IUtilitiesModule { - implements ILocalizationModule, IWaitingsModule { + implements ILocalizationModule, IUtilitiesModule, IWaitingsModule { private final Provider applicationProvider; diff --git a/src/test/java/tests/configurations/EnvConfigurationTests.java b/src/test/java/tests/configurations/EnvConfigurationTests.java index 0c792a7..cab602d 100644 --- a/src/test/java/tests/configurations/EnvConfigurationTests.java +++ b/src/test/java/tests/configurations/EnvConfigurationTests.java @@ -1,11 +1,6 @@ package tests.configurations; import aquality.selenium.core.applications.AqualityModule; -import aquality.selenium.core.configurations.IElementCacheConfiguration; -import aquality.selenium.core.configurations.ILoggerConfiguration; -import aquality.selenium.core.configurations.IRetryConfiguration; -import aquality.selenium.core.configurations.ITimeoutConfiguration; -import aquality.selenium.core.application.AqualityModule; import aquality.selenium.core.configurations.*; import aquality.selenium.core.utilities.ISettingsFile; import org.testng.Assert; diff --git a/src/test/java/tests/configurations/ProfileConfigurationTests.java b/src/test/java/tests/configurations/ProfileConfigurationTests.java index 65ca6bf..4b81c44 100644 --- a/src/test/java/tests/configurations/ProfileConfigurationTests.java +++ b/src/test/java/tests/configurations/ProfileConfigurationTests.java @@ -1,10 +1,8 @@ package tests.configurations; -import aquality.selenium.core.application.AqualityModule; +import aquality.selenium.core.applications.AqualityModule; import aquality.selenium.core.configurations.LoggerConfiguration; import aquality.selenium.core.utilities.ISettingsFile; -import aquality.selenium.core.applications.AqualityModule; -import aquality.selenium.core.configurations.ILoggerConfiguration; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import tests.application.CustomAqualityServices; From dffe9ec07d775d9d9da8726df6ca512615f94062 Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Mon, 3 Feb 2020 18:23:03 +0300 Subject: [PATCH 37/38] optimized import --- .../selenium/core/applications/AqualityModule.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/aquality/selenium/core/applications/AqualityModule.java b/src/main/java/aquality/selenium/core/applications/AqualityModule.java index 45dd9d0..7bb3f17 100644 --- a/src/main/java/aquality/selenium/core/applications/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityModule.java @@ -1,15 +1,15 @@ package aquality.selenium.core.applications; import aquality.selenium.core.configurations.*; -import aquality.selenium.core.localization.*; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.localization.ILocalizationModule; +import aquality.selenium.core.localization.ILocalizedLogger; import aquality.selenium.core.logging.Logger; import aquality.selenium.core.utilities.IElementActionRetrier; import aquality.selenium.core.utilities.ISettingsFile; -import aquality.selenium.core.utilities.JsonSettingsFile; +import aquality.selenium.core.utilities.IUtilitiesModule; import aquality.selenium.core.waitings.IConditionalWait; -import aquality.selenium.core.configurations.*; import aquality.selenium.core.waitings.IWaitingsModule; -import aquality.selenium.core.utilities.IUtilitiesModule; import com.google.inject.AbstractModule; import com.google.inject.Provider; import com.google.inject.Singleton; From 56b874b662ce56a0ec4e5f51166e9d04eca8e41c Mon Sep 17 00:00:00 2001 From: Sergey Knysh Date: Tue, 4 Feb 2020 10:14:35 +0300 Subject: [PATCH 38/38] fixed tests --- src/test/java/tests/waitings/WaitForObjectTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/tests/waitings/WaitForObjectTests.java b/src/test/java/tests/waitings/WaitForObjectTests.java index 07f9f88..c5d38c0 100644 --- a/src/test/java/tests/waitings/WaitForObjectTests.java +++ b/src/test/java/tests/waitings/WaitForObjectTests.java @@ -1,5 +1,6 @@ package tests.waitings; +import org.openqa.selenium.TimeoutException; import org.openqa.selenium.support.ui.ExpectedCondition; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -8,7 +9,6 @@ import java.util.Collections; import java.util.concurrent.Callable; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BooleanSupplier; @@ -32,11 +32,11 @@ public void quit() { } @DataProvider(name = "failWaitForAction", parallel = true) - public Object[][] successWaitForAction1() { + public Object[][] failWaitForAction() { return getDataProvider((app) -> false); } - @Test(dataProvider = "successWaitForAction") + @Test(dataProvider = "failWaitForAction") public void testShouldThrowTimeoutExceptionIfConditionIsNotMetAndTimeoutIsOver(Callable failedAction, long timeout) throws Exception { timer.get().start(); try {