diff --git a/Documentation.en.md b/Documentation.en.md index 06e7d95..ea446fb 100644 --- a/Documentation.en.md +++ b/Documentation.en.md @@ -25,7 +25,7 @@ The main benefits from using Aquality Selenium: - 2.9. ACCESS FROM THE CODE - 3. BROWSER - 3.1. PARALLEL RUNS - - 3.2. BROWSER MANAGER + - 3.2. AQUALITY SERVICES - 3.3. BROWSER FACTORY - 3.4. DRIVER CAPABILITIES - 3.5. DOWNLOAD DIRECTORY @@ -90,7 +90,7 @@ There are some niceties with using InternetExplorer browser. We tried to describ [settings.json](./src/main/resources/settings.json) contains section `timeouts`. It includes list of timeout parameters that are used in the Aquality. -All parameters are used to initialise [TimeoutConfiguration](./src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java) class instance. After initialising parameters can be fetched by call `Configuration.getInstance().getTimeoutConfiguration()`. +All parameters are used to initialise [TimeoutConfiguration](./src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java) class instance. After initialising parameters can be fetched by call `AqualityServices.getConfiguration().getTimeoutConfiguration()`. Below is a description of timeouts: @@ -110,10 +110,10 @@ It is not recommended to use implicit and explicit waits together. `retry` section of [settings.json](./src/main/resources/settings.json) is responsible to configure number of attempts of manipulations with element (click, type, focus and etc.) All the operations can be executed several times if they failed at first attempt. -This logic is implemented in the [ElementActionRetrier](./src/main/java/aquality/selenium/utils/ElementActionRetrier.java) class. This class is used for any manipulations with elements. +This logic is implemented in the [ElementActionRetrier](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/utilities/ElementActionRetrier.java) class. This class is used for any manipulations with elements. `number` parameter keeps value of number of attempts. An exception will be thrown if attempts are over. `pollingInterval` keeps value of interval in **milliseconds** between attempts. -[ElementActionRetrier](./src/main/java/aquality/selenium/utils/ElementActionRetrier.java) catches StaleElementReferenceException and InvalidElementStateException by default. +[ElementActionRetrier](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/utilities/ElementActionRetrier.java) catches StaleElementReferenceException and InvalidElementStateException by default. #### 2.6. LOGGING Aquality logs operations that executes (interaction with browser, elements of the pages). Example of some log: @@ -139,13 +139,19 @@ If parameter has value `true` user will be able to see actions more explicit (re #### 2.9. ACCESS FROM THE CODE -Sometimes you need access to values from settings file from the code. To get it use [Configuration](./src/main/java/aquality/selenium/configuration/Configuration.java) class instance. +Sometimes you need access to values from settings file from the code. To get it you can use [Configuration](./src/main/java/aquality/selenium/configuration/IConfiguration.java) class instance. Example of usage: ``` -Configuration.getInstance().getBrowserProfile().getBrowserName() +AqualityServices.getConfiguration().getBrowserProfile().getBrowserName() ``` returns value of parameter "browser". +You can also resolve the needed configuration from the AqualityServices directly: +```java +AqualityServices.get(IRetryConfiguration.class).getNumber(); // returns number of retry attempts for element actions, e.g. clicking. +AqualityServices.getBrowserProfile(); // returns currently used set of browser settings. +``` + ### **3. BROWSER** Class Browser is a facade around WebDriver and provides methods to work with Browser window and WebDriver itself (for example: navigate, maximize window and etc.). @@ -161,27 +167,32 @@ Examples of using Aquality Selenium in multi-thread mode are here [BrowserConcur Test runners like TestNG, JUnit and etc. start each test in the separate thread from the box. So users do not need to do additional work if they are using such runners. -To use parallel streams that provided by Java from 8th version it is necessary to use BrowserManager to pass correct instance of Browser to stream function. Else parallel stream will create new Browser instances for each thread. +To use parallel streams that provided by Java from 8th version it is necessary to use AqualityServices to pass correct instance of Browser to stream function. Else parallel stream will create new Browser instances for each thread. The example of usage parallel streams is here [testShouldBePossibleToUseParallelStreams](./src/test/java/tests/usecases/BrowserConcurrencyTests.java). -#### 3.2. BROWSER MANAGER +#### 3.2. AQUALITY SERVICES +Class [AqualityServices](https://github.com/aquality-automation/aquality-selenium-java/blob/Feature/Reference-aquality.selenium.core/src/main/java/aquality/selenium/browser/AqualityServices.java) provides static methods to access Browser and other utilities included in the library. + +Usage of AqualityServices is thread-safe. Inside AqualityServices uses DI container Guice. + +You can override any service implementation in the class extended from [BrowserModule](https://github.com/aquality-automation/aquality-selenium-java/blob/Feature/Reference-aquality.selenium.core/src/main/java/aquality/selenium/browser/BrowserModule.java), and then re-initialize AqualityServices in your code using the method ```AqualityServices.initInjector(customModule)```. +Take a look at example of custom module implementation here: [BrowserFactoryTests](https://github.com/aquality-automation/aquality-selenium-java/blob/Feature/Reference-aquality.selenium.core/src/test/java/tests/usecases/BrowserFactoryTests.java) + +#### 3.3. BROWSER FACTORY There are several ways to create instance of class Browser. -The main approach based on the usage of `BrowserManager` class and it's static methods. Below are options of `BrowserManager` usage. +The main approach based on the usage of `AqualityServices` class and it's static methods. Below are options of `AqualityServices` usage. For most cases users need to get Browser instance based on data from the settings file. To get Browser in this case use following: ``` -Browser browser = BrowserManager.getBrowser() +Browser browser = AqualityServices.getBrowser() ``` The first call of `getBrowser()` method will create instance of Browser with WebDriver inside (browser window will be opened). The next calls of `getBrowser()` in the same thread will return the same instance. - -#### 3.3. BROWSER FACTORY - -Implicitly for users `BrowserManager` provides `Browser` through calls to browser factories. +Implicitly for users `AqualityServices` provides `Browser` through calls to browser factories. Aquality Selenium implements following factories: - [LocalBrowserFactory](./src/main/java/aquality/selenium/browser/LocalBrowserFactory.java) - to creating Browser on local machine (parameter `isRemote=false`) @@ -190,19 +201,18 @@ Aquality Selenium implements following factories: Each factory implementation implements interface `IBrowserFactory` with the single method `Browser` `getBrowser()`. Users are allowed to create their on implementations if necessary. -To use custom factory implementation users should set it into `BrowserManager` before first call of `getBrowser()` method: +To use custom factory implementation users should set it into `AqualityServices` before first call of `getBrowser()` method: ``` -BrowserManager.setFactory(IBrowserFactory browserFactory) +AqualityServices.setFactory(IBrowserFactory browserFactory) ``` The examples of usages custom factories can be found here [BrowserFactoryTests](./src/test/java/tests/usecases/BrowserFactoryTests.java) -If there are reasons to not to use factories user is able to create Browser instance using constructor and then put it into BrowserManager: +If there are reasons to not to use factories user is able to create Browser instance using constructor and then put it into AqualityServices: ``` -BrowserManager.setBrowser(Browser browser) +AqualityServices.setBrowser(Browser browser) ``` -Browser class has public constructor with the signature: `Browser(RemoteWebDriver remoteWebDriver, IСonfiguration configuration)`. -User should implement his own implementation of `IConfiguration` - but existing IConfiguration implementation can be used, inherited, used partially(`IDriverSettings`, `ITimeoutConfiguration` and etc.) +Browser class has public constructor with the signature: `Browser(RemoteWebDriver remoteWebDriver)`. Other needed services are resolved from the DI container. For example, user could implement his own implementation of `IConfiguration` - but existing IConfiguration implementation can be used, inherited, used partially(`IDriverSettings`, `ITimeoutConfiguration` and etc.) #### 3.4. DRIVER CAPABILITIES @@ -242,7 +252,7 @@ But there are no restrictions to add your own implementation. `Browser` class provides methods to work with alerts and prompts dialogs: ``` -BrowserManager.getBrowser().handleAlert(AlertActions.ACCEPT); +AqualityServices.getBrowser().handleAlert(AlertActions.ACCEPT); ``` More examples here: [AlertTests.java](./src/test/java/tests/integration/AlertTests.java). @@ -251,7 +261,7 @@ More examples here: [AlertTests.java](./src/test/java/tests/integration/AlertTes To take a screenshot of the page there is the method: ``` -BrowserManager.getBrowser().getScreenshot() +AqualityServices.getBrowser().getScreenshot() ``` Example of taking screenshots here: [testShouldBePossibleToMakeScreenshot](./src/test/java/tests/integration/BrowserTests.java) @@ -266,7 +276,7 @@ When Browser instantiated and navigation to necessary page is done user can begi Below is an example of getting ITextBox element: ``` -ElementFactory elementFactory = new ElementFactory(); +IElementFactory elementFactory = AqualityServices.getElementFactory(); ITextBox txbUsername = elementFactory.getTextBox(By.id("username"), "Username"); ``` `ElementFactory` is able to build elements of any types that implements `IElement` interface. @@ -275,7 +285,7 @@ ITextBox txbUsername = elementFactory.getTextBox(By.id("username"), "Username"); #### 4.2. CUSTOM ELEMENTS User has abilities to create his own type of element by implementing interface or using inheritance. -For this goal `ElementFactory` provides method \<T extends IElement\> T getCustomElement. +For this goal `ElementFactory` provides method ` T getCustomElement`. Example of creating custom element here [CustomElementTests](./src/test/java/tests/usecases/CustomElementTests.java). #### 4.3. LIST OF ELEMENTS @@ -340,16 +350,21 @@ There are several overrided methods that takes scripts as String, File or JavaSc ### **7. JSON FILE** -Aquality Selenium uses [JsonFile](./src/main/java/aquality/selenium/utils/JsonFile.java) class to process the JSON files. +Aquality Selenium uses [JsonSettingsFile](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java) class to process the JSON files. Users can use this class to process JSON files from their own project. For example, if user wants to keep URL to web site that is automating he can put this URL in some JSON file and read value with mentioned class: ``` -JsonFile environment = new JsonFile("settings.json") +ISettingsFile environment = new JsonSettingsFile("settings.json") String url = environment.getValue("/url").toString(); ``` ### **8. CONDITIONAL WAIT** -If you need to wait for any condition to be met, you can use the [ConditionalWait](./src/main/java/aquality/selenium/waitings/ConditionalWait.java) class provided by Aquality Selenium. +If you need to wait for any condition to be met, you can use the [ConditionalWait](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java) class provided by Aquality Selenium. +```java +File fileDownloaded = new File(downloadDirInitialized + fileName); +AqualityServices.getConditionalWait().waitForTrue(() -> fileDownloaded.exists(), + Duration.ofSeconds(120), Duration.ofMillis(300), "File should be downloaded"); +``` All class methods wait for the condition to be met, but return values and handle exceptions ​​differently: 1. ```waitForTrue``` - throws an exception if the condition is not met, returns nothing. 2. ```boolean waitFor``` - returns true if the condition is fulfilled or false otherwise. Method does not throw any exception. diff --git a/Documentation.ru.md b/Documentation.ru.md index 15ed876..b7b2357 100644 --- a/Documentation.ru.md +++ b/Documentation.ru.md @@ -26,7 +26,7 @@ Aquality Selenium является надстройкой над инструм - 2.9. ACCESS FROM THE CODE - 3. BROWSER - 3.1. PARALLEL RUNS - - 3.2. BROWSER MANAGER + - 3.2. AQUALITY SERVICES - 3.3. BROWSER FACTORY - 3.4. DRIVER CAPABILITIES - 3.5. DOWNLOAD DIRECTORY @@ -88,7 +88,7 @@ Settings файл содержит в себе несколько секций, [settings.json](./src/main/resources/settings.json) содержит секцию `timeouts`, которая включает в себя набор параметров, связанных с различного рода таймаутами, используемыми в решении. -Все параметры данной конфигурации используются для инициализации объекта класса [TimeoutConfiguration](./src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java), доступного впоследствии путем обращения `Configuration.getInstance().getTimeoutConfiguration()`. +Все параметры данной конфигурации используются для инициализации объекта класса [TimeoutConfiguration](./src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java), доступного впоследствии путем обращения `AqualityServices.getConfiguration().getTimeoutConfiguration()`. Ниже приводится описание параметров из секции `timeouts` c их назначением: @@ -106,10 +106,10 @@ Settings файл содержит в себе несколько секций, Секция `retry` файла [settings.json](./src/main/resources/settings.json) отвечает за конфигурацию количества попыток выполнения операций над элементом. Все операции над элементами (нажатия, ввод текста и т.п.) могут быть выполнены повторно в случае неудачи. -Данная логика заложена в классе [ElementActionRetrier](./src/main/java/aquality/selenium/utils/ElementActionRetrier.java) посредством которого выполняются любые операции. +Данная логика заложена в классе [ElementActionRetrier](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/utilities/ElementActionRetrier.java) посредством которого выполняются любые операции. Параметр `number` означает количество предпринимаемых попыток выполнить операцию прежде чем выбросить исключение. Параметр `pollingInterval` означает интервал между попытками в миллисекудах. -[ElementActionRetrier](./src/main/java/aquality/selenium/utils/ElementActionRetrier.java) автоматически отлавливает исключения StaleElementReferenceException и ElementNotInteractableException) и повторяет попытку снова. +[ElementActionRetrier](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/utilities/ElementActionRetrier.java) автоматически отлавливает исключения StaleElementReferenceException и ElementNotInteractableException) и повторяет попытку снова. #### 2.6. LOGGING Решение поддерживает логирование выполняемых операций (взаимодействие с браузером, элементами страницы). Пример логирования: @@ -134,13 +134,19 @@ Settings файл содержит в себе несколько секций, #### 2.9. ACCESS FROM THE CODE -Доступ к данным из конфигурационного файла обеспечивается посредством обращения к методам экземпляра класса [Configuration](./src/main/java/aquality/selenium/configuration/Configuration.java) +Доступ к данным из конфигурационного файла обеспечивается посредством обращения к методам экземпляра класса [Configuration](./src/main/java/aquality/selenium/configuration/IConfiguration.java) Например: ``` -Configuration.getInstance().getBrowserProfile().getBrowserName() +AqualityServices.getConfiguration().getBrowserProfile().getBrowserName() ``` вернёт значение параметра "browser" из settings файла. +Также, вы можете получить нужный вам класс конфигурации через AqualityServices напрямую: +```java +AqualityServices.get(IRetryConfiguration.class).getNumber(); // вернёт количество попыток для действий над элементом, напр. нажатия +AqualityServices.getBrowserProfile(); // вернёт текущий набор настроек браузера. +``` + ### **3. BROWSER** Класс Browser, являющийся своего рода фасадом для WebDriver и содержит методы работы с окном браузера и непосредственно с WebDriver (например, navigate, maximize window и т.д.). Написание скрипта начинается с создания экземпляра `Browser` - подробнее об этом ниже. @@ -153,37 +159,41 @@ Configuration.getInstance().getBrowserProfile().getBrowserName() Если вы используете стандартные средства параллелизации, предоставляемые такими инструментами как TestNG, JUnit и т.п., для каждого потока будет автоматически создан свой экземпляр Browser. -Если вы хотите использовать parallel streams доступных в Java начиная с 8ой версии, необходимо использовать BrowserManager для установки текущей версии Browser, иначе parallel stream создаст по одному новому браузеру на каждый параллельный поток. +Если вы хотите использовать parallel streams доступных в Java начиная с 8ой версии, необходимо использовать AqualityServices для установки текущей версии Browser, иначе parallel stream создаст по одному новому браузеру на каждый параллельный поток. Пример использования parallel streams приводится в [testShouldBePossibleToUseParallelStreams](./src/test/java/tests/usecases/BrowserConcurrencyTests.java). -#### 3.2. BROWSER MANAGER +#### 3.2. AQUALITY SERVICES +Класс [AqualityServices](https://github.com/aquality-automation/aquality-selenium-java/blob/Feature/Reference-aquality.selenium.core/src/main/java/aquality/selenium/browser/AqualityServices.java) предоставляет статические методы для доступа к классу Browser и другим утилитам, включённым в данную библиотеку. + +Использование AqualityServices потокобезопасно. Внутри AqualityServices используют DI контейнер Guice. + +Вы можете переопределить реализацию любого из сервисов в классе, отнаследованом от [BrowserModule](https://github.com/aquality-automation/aquality-selenium-java/blob/Feature/Reference-aquality.selenium.core/src/main/java/aquality/selenium/browser/BrowserModule.java), и затем проинициализировать AqualityServices в коде, используя метод ```AqualityServices.initInjector(customModule)```. +Пример использования своей реализации модуля тут: [BrowserFactoryTests](https://github.com/aquality-automation/aquality-selenium-java/blob/Feature/Reference-aquality.selenium.core/src/test/java/tests/usecases/BrowserFactoryTests.java) + +#### 3.3. BROWSER FACTORY -Существует несколько вариантов инициализации Browser. Основной способ базируется на использовании класса `BrowserManager` c набором статических методов для получения `Browser`. Ниже рассматриваются варианты работы с `BrowserManager`. +Существует несколько вариантов инициализации Browser. Основной способ базируется на использовании класса `AqualityServices` c набором статических методов для получения `Browser`. Ниже рассматриваются варианты работы с `AqualityServices`. Если нам необходимо получить браузер с данными из конфигурационого settings файла то достаточно просто произвести вызов: ``` -Browser browser = BrowserManager.getBrowser() +Browser browser = AqualityServices.getBrowser() ``` Первый вызов `getBrowser()` создаст необходимый экземпляр с WebDriver (откроется окно браузера, если только не задан headless режим). Все последующие обращения в рамках одного потока будут работать с созданным экземпляром. - -#### 3.3. BROWSER FACTORY - -Неявно для пользователя `BrowserManager` предоставляет `Browser` посредством обращения к фабрике браузеров. В решение существуют следующие реализации фабрик: +Неявно для пользователя `AqualityServices` предоставляет `Browser` посредством обращения к фабрике браузеров. В решение существуют следующие реализации фабрик: - [LocalBrowserFactory](./src/main/java/aquality/selenium/browser/LocalBrowserFactory.java) - для создания браузера в случае использования параметра `isRemote=false` - [RemoteBrowserFactory](./src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java) - для создания браузера в случае использования параметра `isRemote=true` Каждая реализация фабрики реализует интерфейс `IBrowserFactory` с единственным методом `Browser` `getBrowser()`. Это предоставляет возможность реализовать свою фабрику. -Чтобы `getBrowser()` возвращал `Browser`, созданный вашей реализацией фабрики, необходимо до первого вызова `getBrowser()` установить в `BrowserManager` свою реализацию фабрики, +Чтобы `getBrowser()` возвращал `Browser`, созданный вашей реализацией фабрики, необходимо до первого вызова `getBrowser()` установить в `AqualityServices` свою реализацию фабрики, используя метод `setFactory(IBrowserFactory browserFactory)`. Примеры использования собственной фабрики можно рассмотреть здесь [BrowserFactoryTests](./src/test/java/tests/usecases/BrowserFactoryTests.java) -Если по каким либо причинам вы решите отказаться от использования фабрик, у вас остается возможность создать экземпляр `Browser` самостоятельно и в дальнейшем установить его в `BrowserManager.setBrowser(Browser browser)`. -Класс Browser содержит публичный конструктор со следующей сигнатурой `Browser(RemoteWebDriver remoteWebDriver, IСonfiguration configuration)`. -При этом, для создания собсвенной реализации `IConfiguration`, вам по прежнему доступно использовать уже имеющиеся реализации `IDriverSettings`, `ITimeoutConfiguration` и т.д. +Если по каким либо причинам вы решите отказаться от использования фабрик, у вас остается возможность создать экземпляр `Browser` самостоятельно и в дальнейшем установить его в `AqualityServices.setBrowser(Browser browser)`. +Класс Browser содержит публичный конструктор со следующей сигнатурой `Browser(RemoteWebDriver remoteWebDriver)`. Остальные необходимые сервисы получаются из DI контейнера. К примеру, вы можете создать свою реализацию `IConfiguration` - но при этом вам по прежнему доступно использовать уже имеющуюся реализацию Configuration, наследоваться от неё, использовать имеющиеся реализации `IDriverSettings`, `ITimeoutConfiguration` и т.д. #### 3.4. DRIVER CAPABILITIES @@ -220,7 +230,7 @@ Browser browser = BrowserManager.getBrowser() Класс `Browser` предоставляет методы работы с Alerts: ``` -BrowserManager.getBrowser().handleAlert(AlertActions.ACCEPT); +AqualityServices.getBrowser().handleAlert(AlertActions.ACCEPT); ``` Больше примеров использования можно найти здесь [AlertTests.java](./src/test/java/tests/integration/AlertTests.java). @@ -229,7 +239,7 @@ BrowserManager.getBrowser().handleAlert(AlertActions.ACCEPT); Для получения снимков экрана класс Browser предоставляет метод ``` -BrowserManager.getBrowser().getScreenshot() +AqualityServices.getBrowser().getScreenshot() ``` Более подробный пример использования смотрите в тесте [testShouldBePossibleToMakeScreenshot](./src/test/java/tests/integration/BrowserTests.java) @@ -243,15 +253,15 @@ BrowserManager.getBrowser().getScreenshot() Решение включает класс [ElementFactory](./src/main/java/aquality/selenium/elements/ElementFactory.java), который отвечает за создание элемента необходимого типа. Ниже приводится пример получения ITextBox: ``` -ElementFactory elementFactory = new ElementFactory(); +IElementFactory elementFactory = AqualityServices.getElementFactory(); ITextBox txbUsername = elementFactory.getTextBox(By.id("username"), "Username"); ``` -ElementFactory` способна создавать объекты любых классов, реализующих интерфейс `IElement`. -ElementFactory` содержит ряд методов, которые возвращают реализации `IElement`, имеющиеся по умолчанию в решении (`IButton`, `ITextBox`, `ICheckbox` и т.д.). Обратите внимание, что работа с элементами ведется через интерфейсы, чтобы пользователь обращал внимание только на функциональность, но не на реализацию. +`ElementFactory` способна создавать объекты любых классов, реализующих интерфейс `IElement`. +`ElementFactory` содержит ряд методов, которые возвращают реализации `IElement`, имеющиеся по умолчанию в решении (`IButton`, `ITextBox`, `ICheckbox` и т.д.). Обратите внимание, что работа с элементами ведется через интерфейсы, чтобы пользователь обращал внимание только на функциональность, но не на реализацию. #### 4.2. CUSTOM ELEMENTS -Пользователь имеет возможность создать свой элемент или расширить имеющийся по умолчанию. Для этих целей `ElementFactory` предоставляет метод \<T extends IElement\> T getCustomElement. Достаточно или реализовать `IElement` интерфейс или расширить имеющийся класс элемента. С примером расширения и последующего использования можно ознакомиться в классе [CustomElementTests](./src/test/java/tests/usecases/CustomElementTests.java). +Пользователь имеет возможность создать свой элемент или расширить имеющийся по умолчанию. Для этих целей `ElementFactory` предоставляет метод ` T getCustomElement`. Достаточно или реализовать `IElement` интерфейс или расширить имеющийся класс элемента. С примером расширения и последующего использования можно ознакомиться в классе [CustomElementTests](./src/test/java/tests/usecases/CustomElementTests.java). #### 4.3. LIST OF ELEMENTS @@ -312,17 +322,22 @@ browser.executeScript(final String script, Object... arguments). ### **7. JSON FILE** -Aquality Selenium использует для своей работы и предоставляет доступ к классу [JsonFile](./src/main/java/aquality/selenium/utils/JsonFile.java). +Aquality Selenium использует для своей работы и предоставляет доступ к классу [JsonSettingsFile](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/utilities/JsonSettingsFile.java). Данный класс предоставляет удобные методы для работы с JSON файлами вашего проекта. Например, если вы захотите хранить URL сайта с которым вы работаете как параметр конфигурации вы сможете считывать значения из JSON при помощи указанного класса: ``` -JsonFile environment = new JsonFile("settings.json") +ISettingsFile environment = new JsonSettingsFile("settings.json") String url = environment.getValue("/url").toString(); ``` ### **8. CONDITIONAL WAIT** -В случае необходимости ожидания выполнения какого-либо условия можно воспользоваться предоставляемым в Aquality Selenium классом [ConditionalWait](./src/main/java/aquality/selenium/waitings/ConditionalWait.java). +В случае необходимости ожидания выполнения какого-либо условия можно воспользоваться предоставляемым в Aquality Selenium классом [ConditionalWait](https://github.com/aquality-automation/aquality-selenium-core-java/blob/master/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java). +```java +File fileDownloaded = new File(downloadDirInitialized + fileName); +AqualityServices.getConditionalWait().waitForTrue(() -> fileDownloaded.exists(), + Duration.ofSeconds(120), Duration.ofMillis(300), "File should be downloaded"); +``` Все методы класса ждут выполнения условия, но по разному возвращают значения и обрабатывают ошибки: 1. waitForTrue - выкидывает ошибку в случае, если условие не выполнилось, ничего не возвращает. 2. boolean waitFor - возвращает true если условие выполнилось или false если не выполнилось, ошибок не выбрасывает. diff --git a/README.md b/README.md index 32d9457..35c0542 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,13 @@ We use interfaces where is possible, so you can implement your own version of ta com.github.aquality-automation aquality-selenium - 1.2.1 + 2.0.0 ``` 2. Create instance of Browser in your test method: ```java -Browser browser = BrowserManager.getBrowser(); +Browser browser = AqualityServices.getBrowser(); ``` 3. Use Browser's methods directly for general actions, such as navigation, window resize, scrolling and alerts handling: @@ -36,7 +36,7 @@ browser.waitForPageToLoad(); 4. Use ElementFactory class's methods to get an instance of each element. ```java -ITextBox txbSearch = new ElementFactory().getTextBox(By.id("searchInput"), "Search"); +ITextBox txbSearch = AqualityServices.getElementFactory().getTextBox(By.id("searchInput"), "Search"); ``` 5. Call element's methods to perform action with element: diff --git a/pom.xml b/pom.xml index 67099cc..748847b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.aquality-automation aquality-selenium - 1.2.1 + 2.0.0 jar Aquality Selenium @@ -64,9 +64,19 @@ sunigos Igor Sontsa + + knysh + Sergey Knysh + + + com.github.aquality-automation + aquality-selenium-core + 0.0.2 + + org.seleniumhq.selenium selenium-java diff --git a/src/main/java/aquality/selenium/browser/AqualityServices.java b/src/main/java/aquality/selenium/browser/AqualityServices.java new file mode 100644 index 0000000..0c71400 --- /dev/null +++ b/src/main/java/aquality/selenium/browser/AqualityServices.java @@ -0,0 +1,173 @@ +package aquality.selenium.browser; + +import aquality.selenium.configuration.IBrowserProfile; +import aquality.selenium.configuration.IConfiguration; +import aquality.selenium.core.localization.ILocalizedLogger; +import aquality.selenium.core.logging.Logger; +import aquality.selenium.core.waitings.IConditionalWait; +import aquality.selenium.elements.interfaces.IElementFactory; +import com.google.inject.Injector; + +/** + * Controls browser and Aquality services. + */ +public class AqualityServices extends aquality.selenium.core.applications.AqualityServices { + private static final ThreadLocal INSTANCE_CONTAINER = ThreadLocal.withInitial(AqualityServices::new); + private IBrowserFactory browserFactory; + + private AqualityServices() { + super(AqualityServices::getBrowser, () -> new BrowserModule(AqualityServices::getBrowser)); + } + + private AqualityServices(BrowserModule module) { + super(AqualityServices::getBrowser, () -> module); + } + + private static AqualityServices getInstance() { + return INSTANCE_CONTAINER.get(); + } + + /** + * Gets instance of browser. + * + * @return Instance of desired browser. + */ + public static Browser getBrowser() { + return getInstance().getApp(injector -> AqualityServices.startBrowser()); + } + + /** + * Check if browser already started or not. + * + * @return true if browser started and false otherwise. + */ + public static boolean isBrowserStarted() { + return getInstance().isAppStarted(); + } + + /** + * Resolves required service from DI container. + * Note that the service should be binded in {@link BrowserModule}. + * + * @param type class of required service. + * @param type of required service. + * @return required service. + */ + public static T get(Class type) { + return getServiceProvider().getInstance(type); + } + + private static Injector getServiceProvider() { + return getInstance().getInjector(); + } + + /** + * Sets default(local {@link LocalBrowserFactory} or remote {@link RemoteBrowserFactory}) browser factory. + */ + public static void setDefaultBrowserFactory() { + IBrowserFactory browserFactory = getBrowserProfile().isRemote() + ? new RemoteBrowserFactory() : new LocalBrowserFactory(); + setBrowserFactory(browserFactory); + } + + /** + * Gets factory for browser creation. + * + * @return current instance of browser factory. + */ + public static IBrowserFactory getBrowserFactory() { + if (getInstance().browserFactory == null) { + setDefaultBrowserFactory(); + } + + return getInstance().browserFactory; + } + + /** + * Sets custom browser factory. + * + * @param browserFactory Custom implementation of {@link IBrowserFactory} + */ + public static void setBrowserFactory(IBrowserFactory browserFactory) { + getInstance().browserFactory = browserFactory; + } + + private static Browser startBrowser() { + return getBrowserFactory().getBrowser(); + } + + /** + * Sets instance of browser. + * + * @param browser Instance of desired browser. + */ + public static void setBrowser(Browser browser) { + getInstance().setApp(browser); + } + + /** + * Reinitializes the dependency injector with custom {@link BrowserModule}. + * + * @param module {@link BrowserModule} object with custom or overriden services. + */ + public static void initInjector(BrowserModule module) { + if (INSTANCE_CONTAINER.get() != null) { + INSTANCE_CONTAINER.remove(); + } + INSTANCE_CONTAINER.set(new AqualityServices(module)); + } + + /** + * Gets logger. + * + * @return instance of logger. + */ + public static Logger getLogger() { + return get(Logger.class); + } + + /** + * Gets logger which logs messages in current language. + * + * @return instance of localized logger. + */ + public static ILocalizedLogger getLocalizedLogger() { + return get(ILocalizedLogger.class); + } + + /** + * Provides the utility used to wait for some condition. + * + * @return instance of conditional wait. + */ + public static IConditionalWait getConditionalWait() { + return get(IConditionalWait.class); + } + + /** + * Gets factory to create elements. + * + * @return Factory of elements. + */ + public static IElementFactory getElementFactory() { + return get(IElementFactory.class); + } + + /** + * Gets current profile of browser settings. + * + * @return current browser profile. + */ + public static IBrowserProfile getBrowserProfile() { + return get(IBrowserProfile.class); + } + + /** + * Provides interface to access all described configurations. + * + * @return configuration. + */ + public static IConfiguration getConfiguration() { + return get(IConfiguration.class); + } +} diff --git a/src/main/java/aquality/selenium/browser/Browser.java b/src/main/java/aquality/selenium/browser/Browser.java index ba67a8e..e3315d5 100644 --- a/src/main/java/aquality/selenium/browser/Browser.java +++ b/src/main/java/aquality/selenium/browser/Browser.java @@ -1,10 +1,11 @@ package aquality.selenium.browser; -import aquality.selenium.configuration.IConfiguration; +import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.ITimeoutConfiguration; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; -import aquality.selenium.waitings.ConditionalWait; +import aquality.selenium.core.applications.IApplication; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.localization.ILocalizedLogger; +import aquality.selenium.core.waitings.IConditionalWait; import org.apache.commons.io.IOUtils; import org.openqa.selenium.Alert; import org.openqa.selenium.Dimension; @@ -13,26 +14,33 @@ import org.openqa.selenium.WebDriver.Navigation; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; + import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; -public class Browser { - private final Logger logger = Logger.getInstance(); +public class Browser implements IApplication { private final RemoteWebDriver webDriver; private final ITimeoutConfiguration timeouts; - private Long timeoutImpl; - private IConfiguration configuration; - - - public Browser(RemoteWebDriver remoteWebDriver, IConfiguration configuration) { + private Duration timeoutImpl; + private final IBrowserProfile browserProfile; + private final IConditionalWait conditionalWait; + private final ILocalizationManager localizationManager; + private final ILocalizedLogger localizedLogger; + + + public Browser(RemoteWebDriver remoteWebDriver) { + conditionalWait = AqualityServices.getConditionalWait(); + localizationManager = AqualityServices.get(ILocalizationManager.class); + localizedLogger = AqualityServices.getLocalizedLogger(); + this.browserProfile = AqualityServices.getBrowserProfile(); + this.timeouts = AqualityServices.get(ITimeoutConfiguration.class); webDriver = remoteWebDriver; - this.configuration = configuration; - this.timeouts = configuration.getTimeoutConfiguration(); this.timeoutImpl = timeouts.getImplicit(); - getDriver().manage().timeouts().implicitlyWait(timeoutImpl, TimeUnit.SECONDS); + getDriver().manage().timeouts().implicitlyWait(timeoutImpl.getSeconds(), TimeUnit.SECONDS); setPageLoadTimeout(timeouts.getPageLoad()); setScriptTimeout(timeouts.getScript()); } @@ -41,7 +49,7 @@ public Browser(RemoteWebDriver remoteWebDriver, IConfiguration configuration) { * Executes browser quit, closes all windows and dispose session */ public void quit() { - logger.info(getLocManager().getValue("loc.browser.driver.quit")); + localizedLogger.info("loc.browser.driver.quit"); if (getDriver() != null) { getDriver().quit(); } @@ -49,14 +57,21 @@ public void quit() { /** * Provides Selenium WebDriver instance for current browser session + * * @return web driver instance */ public RemoteWebDriver getDriver() { return webDriver; } + @Override + public boolean isStarted() { + return webDriver.getSessionId() != null; + } + /** * Executes navigating by passed URL + * * @param url URL where you wish to navigate */ public void goTo(String url) { @@ -81,16 +96,17 @@ public void goForward() { * Executes browser window maximizing */ public void maximize() { - logger.info(getLocManager().getValue("loc.browser.maximize")); + localizedLogger.info("loc.browser.maximize"); getDriver().manage().window().maximize(); } /** * Returns current page's URL + * * @return current page's URL */ public String getCurrentUrl() { - logger.info(getLocManager().getValue("loc.browser.getUrl")); + localizedLogger.info("loc.browser.getUrl"); return getDriver().getCurrentUrl(); } @@ -103,6 +119,7 @@ public void refresh() { /** * Refreshes the page and process alert that apears after refreshing + * * @param alertAction accept or decline alert */ public void refreshPageWithAlert(AlertActions alertAction) { @@ -110,45 +127,46 @@ public void refreshPageWithAlert(AlertActions alertAction) { handleAlert(alertAction); } - - private Navigation navigate(){ + private Navigation navigate() { return new BrowserNavigation(getDriver()); } /** * Sets page load timeout (Will be ignored for Safari https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/687) + * * @param timeout seconds to wait */ - public void setPageLoadTimeout(Long timeout) { - logger.debug(String.format(getLocManager().getValue("loc.browser.page.load.timeout"), timeout)); - if(!getBrowserName().equals(BrowserName.SAFARI)){ - getDriver().manage().timeouts().pageLoadTimeout(timeout, TimeUnit.SECONDS); + public void setPageLoadTimeout(Duration timeout) { + localizedLogger.debug("loc.browser.page.load.timeout", timeout.getSeconds()); + if (!getBrowserName().equals(BrowserName.SAFARI)) { + getDriver().manage().timeouts().pageLoadTimeout(timeout.getSeconds(), TimeUnit.SECONDS); } } /** * Sets web driver implicit wait timeout * Be careful with using this method. Implicit timeout can affect to duration of driver operations - * @param timeout seconds to wait + * + * @param timeout duration of time to wait */ - public void setImplicitWaitTimeout(Long timeout) { - logger.debug(String.format(getLocManager().getValue("loc.browser.implicit.timeout"), timeout)); - if(!timeout.equals(getImplicitWaitTimeout())){ - getDriver().manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS); + public void setImplicitWaitTimeout(Duration timeout) { + localizedLogger.debug("loc.browser.implicit.timeout", timeout.getSeconds()); + if (!timeout.equals(getImplicitWaitTimeout())) { + getDriver().manage().timeouts().implicitlyWait(timeout.getSeconds(), TimeUnit.SECONDS); timeoutImpl = timeout; } } /** * Sets timeout to async javascript executions + * * @param timeout timeout in seconds */ - public void setScriptTimeout(Long timeout) { - logger.debug(String.format(getLocManager().getValue("loc.browser.script.timeout"), timeout)); - getDriver().manage().timeouts().setScriptTimeout(timeout, TimeUnit.SECONDS); + public void setScriptTimeout(Duration timeout) { + localizedLogger.debug("loc.browser.script.timeout", timeout.getSeconds()); + getDriver().manage().timeouts().setScriptTimeout(timeout.getSeconds(), TimeUnit.SECONDS); } - /** * Waits until page is loaded * TimeoutException will be thrown if page is not loaded during timeout @@ -160,21 +178,21 @@ public void waitForPageToLoad() { Object result = executeScript(JavaScript.IS_PAGE_LOADED.getScript()); return result instanceof Boolean && (Boolean) result; }; - ConditionalWait.waitFor(condition, + conditionalWait.waitFor(condition, timeouts.getPageLoad(), timeouts.getPollingInterval(), - String.format(getLocManager().getValue("loc.browser.page.is.not.loaded"), timeouts.getPageLoad())); + localizationManager.getLocalizedMessage("loc.browser.page.timeout")); } /** * Makes screenshot of the current page + * * @return screenshot as array of bytes */ public byte[] getScreenshot() { return getDriver().getScreenshotAs(OutputType.BYTES); } - /** * Executes JS (jQuery) script asynchronous. * @@ -204,8 +222,8 @@ public Object executeAsyncScript(JavaScript scriptName, Object... args) { * * @param file Java Script file * @param arguments Arguments for the script (web elements, values etc. - * @throws IOException in case of problems with the File * @return Result object of script execution + * @throws IOException in case of problems with the File */ public Object executeAsyncScript(final File file, Object... arguments) throws IOException { return executeAsyncScript(IOUtils.toString(file.toURI(), StandardCharsets.UTF_8.name()), arguments); @@ -222,7 +240,7 @@ public Object executeScript(final String script, Object... arguments) { return executeJavaScript(() -> getDriver().executeScript(script, arguments)); } - private Object executeJavaScript(Supplier executeScriptFunc){ + private Object executeJavaScript(Supplier executeScriptFunc) { Object result = executeScriptFunc.get(); return result instanceof Boolean ? Boolean.parseBoolean(result.toString()) : result; } @@ -245,8 +263,8 @@ public Object executeScript(JavaScript scriptName, Object... args) { * * @param file Java Script file * @param arguments Arguments for the script (web elements, values etc. - * @throws IOException in case of problems with the File * @return Result object of script execution + * @throws IOException in case of problems with the File */ public Object executeScript(final File file, Object... arguments) throws IOException { return executeScript(IOUtils.toString(file.toURI(), StandardCharsets.UTF_8.name()), arguments); @@ -254,40 +272,39 @@ public Object executeScript(final File file, Object... arguments) throws IOExcep /** * Accepts or declines appeared alert + * * @param alertAction accept or decline */ public void handleAlert(AlertActions alertAction) { - try { - Alert alert = getDriver().switchTo().alert(); - if (alertAction.equals(AlertActions.ACCEPT)) - alert.accept(); - else alert.dismiss(); - } catch (NoAlertPresentException exception) { - logger.fatal(getLocManager().getValue("loc.browser.alert.fail"), exception); - throw exception; - } + handlePromptAlert(alertAction, null); } /** * Accepts or declines prompt with sending message + * * @param alertAction accept or decline - * @param text message to send + * @param text message to send */ public void handlePromptAlert(AlertActions alertAction, String text) { try { Alert alert = getDriver().switchTo().alert(); - getDriver().switchTo().alert().sendKeys(text); - if (alertAction.equals(AlertActions.ACCEPT)) + if (text != null && !text.isEmpty()) { + getDriver().switchTo().alert().sendKeys(text); + } + if (alertAction.equals(AlertActions.ACCEPT)) { alert.accept(); - else alert.dismiss(); + } else { + alert.dismiss(); + } } catch (NoAlertPresentException exception) { - logger.fatal(getLocManager().getValue("loc.browser.alert.fail"), exception); + localizedLogger.fatal("loc.browser.alert.fail", exception); throw exception; } } /** * Executes scrolling of the page to given coordinates x and y + * * @param x coordinate x * @param y coordinate y */ @@ -297,36 +314,34 @@ public void scrollWindowBy(int x, int y) { /** * Sets given window size - * @param width desired window width + * + * @param width desired window width * @param height desired window height */ - public void setWindowSize(int width, int height){ + public void setWindowSize(int width, int height) { getDriver().manage().window().setSize(new Dimension(width, height)); } /** * Returns path to download directory * Path is configured during web driver setup by value from settings.json + * * @return path to download directory */ public String getDownloadDirectory() { - return configuration.getBrowserProfile().getDriverSettings().getDownloadDir(); + return browserProfile.getDriverSettings().getDownloadDir(); } /** * Returns name of current browser + * * @return name */ public final BrowserName getBrowserName() { - return configuration.getBrowserProfile().getBrowserName(); + return browserProfile.getBrowserName(); } - private Long getImplicitWaitTimeout() { + private Duration getImplicitWaitTimeout() { return timeoutImpl; } - - private LocalizationManager getLocManager(){ - return LocalizationManager.getInstance(); - } } - diff --git a/src/main/java/aquality/selenium/browser/BrowserFactory.java b/src/main/java/aquality/selenium/browser/BrowserFactory.java index b48076b..62a824b 100644 --- a/src/main/java/aquality/selenium/browser/BrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/BrowserFactory.java @@ -1,22 +1,18 @@ package aquality.selenium.browser; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.logging.Logger; -abstract class BrowserFactory implements IBrowserFactory { +interface BrowserFactory extends IBrowserFactory { - IllegalArgumentException getLoggedWrongBrowserNameException() { - String message = getLocManager().getValue("loc.browser.name.wrong"); + default IllegalArgumentException getLoggedWrongBrowserNameException() { + String message = AqualityServices.get(ILocalizationManager.class).getLocalizedMessage("loc.browser.name.wrong"); IllegalArgumentException exception = new IllegalArgumentException(message); Logger.getInstance().fatal(message, exception); return exception; } - void logBrowserIsReady(BrowserName browserName) { - Logger.getInstance().info(getLocManager().getValue("loc.browser.ready"), browserName.toString()); - } - - private LocalizationManager getLocManager(){ - return LocalizationManager.getInstance(); + default void logBrowserIsReady(BrowserName browserName) { + AqualityServices.getLocalizedLogger().info("loc.browser.ready", browserName.toString()); } } diff --git a/src/main/java/aquality/selenium/browser/BrowserManager.java b/src/main/java/aquality/selenium/browser/BrowserManager.java deleted file mode 100644 index 81c815c..0000000 --- a/src/main/java/aquality/selenium/browser/BrowserManager.java +++ /dev/null @@ -1,67 +0,0 @@ -package aquality.selenium.browser; - -import aquality.selenium.configuration.Configuration; -import aquality.selenium.configuration.IConfiguration; - -/** - * Controls browser instance creation. - */ -public class BrowserManager { - private static final ThreadLocal browserContainer = new ThreadLocal<>(); - private static final ThreadLocal factoryContainer = new ThreadLocal<>(); - - private BrowserManager(){ - } - - /** - * Gets instance of browser. - * @return Instance of desired browser. - */ - public static Browser getBrowser(){ - if(browserContainer.get() == null || browserContainer.get().getDriver().getSessionId() == null) { - setDefaultBrowser(); - } - return browserContainer.get(); - } - - /** - * Sets default(local {@link LocalBrowserFactory} or remote {@link RemoteBrowserFactory}) browser factory. - */ - public static void setDefaultFactory(){ - IConfiguration configuration = Configuration.getInstance(); - IBrowserFactory browserFactory = Configuration.getInstance().getBrowserProfile().isRemote() - ? new RemoteBrowserFactory(configuration) : new LocalBrowserFactory(configuration); - setFactory(browserFactory); - } - - /** - * Sets custom browser factory. - * @param browserFactory Custom implementation of {@link IBrowserFactory} - */ - public static void setFactory(IBrowserFactory browserFactory){ - remove(factoryContainer); - BrowserManager.factoryContainer.set(browserFactory); - } - - private static void setDefaultBrowser(){ - if(factoryContainer.get() == null){ - setDefaultFactory(); - } - setBrowser(factoryContainer.get().getBrowser()); - } - - /** - * Sets instance of browser. - * @param browser Instance of desired browser. - */ - public static void setBrowser(Browser browser){ - remove(browserContainer); - BrowserManager.browserContainer.set(browser); - } - - private static void remove(ThreadLocal container){ - if(container.get() != null){ - container.remove(); - } - } -} diff --git a/src/main/java/aquality/selenium/browser/BrowserModule.java b/src/main/java/aquality/selenium/browser/BrowserModule.java new file mode 100644 index 0000000..2df6a20 --- /dev/null +++ b/src/main/java/aquality/selenium/browser/BrowserModule.java @@ -0,0 +1,24 @@ +package aquality.selenium.browser; + +import aquality.selenium.configuration.*; +import aquality.selenium.core.applications.AqualityModule; +import aquality.selenium.elements.IElementsModule; +import aquality.selenium.elements.interfaces.IElementFactory; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +public class BrowserModule extends AqualityModule implements IConfigurationsModule, IElementsModule { + + public BrowserModule(Provider applicationProvider) { + super(applicationProvider); + } + + @Override + protected void configure() { + super.configure(); + bind(ITimeoutConfiguration.class).to(getTimeoutConfigurationImplementation()).in(Singleton.class); + bind(IBrowserProfile.class).to(getBrowserProfileImplementation()).in(Singleton.class); + bind(IElementFactory.class).to(getElementFactoryImplementation()); + bind(IConfiguration.class).to(getConfigurationImplementation()); + } +} diff --git a/src/main/java/aquality/selenium/browser/BrowserNavigation.java b/src/main/java/aquality/selenium/browser/BrowserNavigation.java index dff101b..c81e50a 100644 --- a/src/main/java/aquality/selenium/browser/BrowserNavigation.java +++ b/src/main/java/aquality/selenium/browser/BrowserNavigation.java @@ -1,7 +1,5 @@ package aquality.selenium.browser; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; import org.openqa.selenium.WebDriver.Navigation; import org.openqa.selenium.remote.RemoteWebDriver; @@ -10,7 +8,6 @@ class BrowserNavigation implements Navigation { private final RemoteWebDriver driver; - private final Logger logger = Logger.getInstance(); BrowserNavigation(RemoteWebDriver driver){ this.driver = driver; @@ -18,31 +15,31 @@ class BrowserNavigation implements Navigation { @Override public void back() { - logger.info(getLocManger().getValue("loc.browser.back")); + infoLoc("loc.browser.back"); getDriver().navigate().back(); } @Override public void forward() { - logger.info(getLocManger().getValue("loc.browser.forward")); + infoLoc("loc.browser.forward"); getDriver().navigate().forward(); } @Override public void to(String s) { - logger.info(getLocManger().getValue("loc.browser.navigate"), s); + infoLoc("loc.browser.navigate", s); getDriver().navigate().to(s); } @Override public void to(URL url) { - logger.info(getLocManger().getValue("loc.browser.navigate"), url); + infoLoc("loc.browser.navigate", url); getDriver().navigate().to(url); } @Override public void refresh() { - logger.info(getLocManger().getValue("loc.browser.refresh")); + infoLoc("loc.browser.refresh"); getDriver().navigate().refresh(); } @@ -50,7 +47,7 @@ private RemoteWebDriver getDriver() { return driver; } - private LocalizationManager getLocManger(){ - return LocalizationManager.getInstance(); + private void infoLoc(String key, Object... args) { + AqualityServices.getLocalizedLogger().info(key, args); } } diff --git a/src/main/java/aquality/selenium/browser/IBrowserFactory.java b/src/main/java/aquality/selenium/browser/IBrowserFactory.java index 8976373..e937c5a 100644 --- a/src/main/java/aquality/selenium/browser/IBrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/IBrowserFactory.java @@ -1,7 +1,7 @@ package aquality.selenium.browser; /** - * Factory that creates instance of desired Browser based on {@link aquality.selenium.configuration.IConfiguration} + * Factory that creates instance of desired Browser based on {@link aquality.selenium.configuration.IBrowserProfile} */ public interface IBrowserFactory { diff --git a/src/main/java/aquality/selenium/browser/JavaScript.java b/src/main/java/aquality/selenium/browser/JavaScript.java index 1a82548..04ea6fc 100644 --- a/src/main/java/aquality/selenium/browser/JavaScript.java +++ b/src/main/java/aquality/selenium/browser/JavaScript.java @@ -1,6 +1,6 @@ package aquality.selenium.browser; -import aquality.selenium.logger.Logger; +import aquality.selenium.core.logging.Logger; import org.apache.commons.io.IOUtils; import java.io.IOException; diff --git a/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java b/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java index ce8cabd..20268ad 100644 --- a/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java @@ -1,8 +1,8 @@ package aquality.selenium.browser; +import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.driversettings.EdgeSettings; import aquality.selenium.configuration.driversettings.IDriverSettings; -import aquality.selenium.configuration.IConfiguration; import io.github.bonigarcia.wdm.Architecture; import io.github.bonigarcia.wdm.WebDriverManager; import org.openqa.selenium.chrome.ChromeDriver; @@ -18,19 +18,19 @@ import java.util.Arrays; -public class LocalBrowserFactory extends BrowserFactory { +public class LocalBrowserFactory implements BrowserFactory { - private final IConfiguration configuration; + private final IBrowserProfile browserProfile; - public LocalBrowserFactory(IConfiguration configuration){ - this.configuration = configuration; + public LocalBrowserFactory() { + this.browserProfile = AqualityServices.getBrowserProfile(); } @Override public Browser getBrowser() { - BrowserName browserName = configuration.getBrowserProfile().getBrowserName(); + BrowserName browserName = browserProfile.getBrowserName(); RemoteWebDriver driver; - IDriverSettings driverSettings = configuration.getBrowserProfile().getDriverSettings(); + IDriverSettings driverSettings = browserProfile.getDriverSettings(); String webDriverVersion = driverSettings.getWebDriverVersion(); Architecture systemArchitecture = Arrays.stream(Architecture.values()) .filter(value -> value.name().equals(driverSettings.getSystemArchitecture())) @@ -61,6 +61,6 @@ public Browser getBrowser() { } logBrowserIsReady(browserName); - return new Browser(driver, configuration); + return new Browser(driver); } } diff --git a/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java b/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java index 0a2f8d4..9d9731b 100644 --- a/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java @@ -1,9 +1,8 @@ package aquality.selenium.browser; -import aquality.selenium.configuration.IConfiguration; +import aquality.selenium.configuration.IBrowserProfile; +import aquality.selenium.configuration.ITimeoutConfiguration; import aquality.selenium.configuration.driversettings.IDriverSettings; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; import com.google.common.collect.ImmutableMap; import org.openqa.selenium.Capabilities; import org.openqa.selenium.remote.CommandExecutor; @@ -11,40 +10,39 @@ import org.openqa.selenium.remote.LocalFileDetector; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.http.HttpClient; +import org.openqa.selenium.remote.http.HttpClient.Builder; +import org.openqa.selenium.remote.http.HttpClient.Factory; import java.net.URL; import java.time.Duration; -public class RemoteBrowserFactory extends BrowserFactory { +public class RemoteBrowserFactory implements BrowserFactory { - private final IConfiguration configuration; + private final IBrowserProfile browserProfile; + private final ITimeoutConfiguration timeoutConfiguration; - public RemoteBrowserFactory(IConfiguration configuration){ - this.configuration = configuration; + public RemoteBrowserFactory() { + browserProfile = AqualityServices.getBrowserProfile(); + timeoutConfiguration = AqualityServices.get(ITimeoutConfiguration.class); } @Override - public Browser getBrowser(){ - BrowserName browserName = getBrowserName(); - IDriverSettings driverSettings = configuration.getBrowserProfile().getDriverSettings(); + public Browser getBrowser() { + BrowserName browserName = browserProfile.getBrowserName(); + IDriverSettings driverSettings = browserProfile.getDriverSettings(); logBrowserIsReady(browserName); RemoteWebDriver driver = createRemoteDriver(driverSettings.getCapabilities()); - return new Browser(driver, configuration); + return new Browser(driver); } - private BrowserName getBrowserName() { - return configuration.getBrowserProfile().getBrowserName(); - } - - private RemoteWebDriver createRemoteDriver(Capabilities capabilities){ - Logger logger = Logger.getInstance(); - logger.info(LocalizationManager.getInstance().getValue("loc.browser.grid")); + private RemoteWebDriver createRemoteDriver(Capabilities capabilities) { + AqualityServices.getLocalizedLogger().info("loc.browser.grid"); ClientFactory clientFactory = new ClientFactory(); CommandExecutor commandExecutor = new HttpCommandExecutor( ImmutableMap.of(), - configuration.getBrowserProfile().getRemoteConnectionUrl(), + browserProfile.getRemoteConnectionUrl(), clientFactory); RemoteWebDriver driver = new RemoteWebDriver(commandExecutor, capabilities); @@ -53,12 +51,12 @@ private RemoteWebDriver createRemoteDriver(Capabilities capabilities){ return driver; } - class ClientFactory implements org.openqa.selenium.remote.http.HttpClient.Factory{ - private final HttpClient.Factory defaultClientFactory = HttpClient.Factory.createDefault(); - private final Duration timeoutCommand = Duration.ofSeconds(configuration.getTimeoutConfiguration().getCommand()); + class ClientFactory implements Factory { + private final Factory defaultClientFactory = Factory.createDefault(); + private final Duration timeoutCommand = timeoutConfiguration.getCommand(); @Override - public HttpClient.Builder builder() { + public Builder builder() { return defaultClientFactory.builder().readTimeout(timeoutCommand); } diff --git a/src/main/java/aquality/selenium/configuration/BrowserProfile.java b/src/main/java/aquality/selenium/configuration/BrowserProfile.java index 85a139c..841aa3e 100644 --- a/src/main/java/aquality/selenium/configuration/BrowserProfile.java +++ b/src/main/java/aquality/selenium/configuration/BrowserProfile.java @@ -2,7 +2,8 @@ import aquality.selenium.browser.BrowserName; import aquality.selenium.configuration.driversettings.*; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; import org.openqa.selenium.InvalidArgumentException; import java.net.MalformedURLException; @@ -10,9 +11,10 @@ public class BrowserProfile implements IBrowserProfile { - private final JsonFile settingsFile; + private final ISettingsFile settingsFile; - public BrowserProfile(JsonFile settingsFile) { + @Inject + public BrowserProfile(ISettingsFile settingsFile) { this.settingsFile = settingsFile; } @@ -62,7 +64,7 @@ public URL getRemoteConnectionUrl() { try { return new URL(String.valueOf(settingsFile.getValue("/" + key))); } catch (MalformedURLException e) { - throw new InvalidArgumentException(String.format("Key %1$s was not found in file %2$s", key, settingsFile.getFileCanonicalPath())); + throw new InvalidArgumentException(String.format("Parameter %1$s was not correct in settings", key)); } } } diff --git a/src/main/java/aquality/selenium/configuration/Configuration.java b/src/main/java/aquality/selenium/configuration/Configuration.java index 0da73f3..1a819f0 100644 --- a/src/main/java/aquality/selenium/configuration/Configuration.java +++ b/src/main/java/aquality/selenium/configuration/Configuration.java @@ -1,25 +1,27 @@ package aquality.selenium.configuration; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.configurations.IElementCacheConfiguration; +import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.configurations.IRetryConfiguration; +import com.google.inject.Inject; -public class Configuration implements IConfiguration{ +public class Configuration implements IConfiguration { - private static ThreadLocal instance = ThreadLocal.withInitial(Configuration::new); private final ITimeoutConfiguration timeoutConfiguration; private final IRetryConfiguration retryConfiguration; private final IBrowserProfile browserProfile; private final ILoggerConfiguration loggerConfiguration; - - private Configuration() { - JsonFile settings = getSettings(); - timeoutConfiguration = new TimeoutConfiguration(settings); - retryConfiguration = new RetryConfiguration(settings); - browserProfile = new BrowserProfile(settings); - loggerConfiguration = new LoggerConfiguration(settings); - } - - public static Configuration getInstance() { - return instance.get(); + private final IElementCacheConfiguration elementCacheConfiguration; + + @Inject + public Configuration(ITimeoutConfiguration timeoutConfiguration, IRetryConfiguration retryConfiguration, + IBrowserProfile browserProfile, ILoggerConfiguration loggerConfiguration, + IElementCacheConfiguration elementCacheConfiguration) { + this.timeoutConfiguration = timeoutConfiguration; + this.retryConfiguration = retryConfiguration; + this.browserProfile = browserProfile; + this.loggerConfiguration = loggerConfiguration; + this.elementCacheConfiguration = elementCacheConfiguration; } @Override @@ -42,8 +44,8 @@ public ILoggerConfiguration getLoggerConfiguration() { return loggerConfiguration; } - private JsonFile getSettings() { - String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json"; - return new JsonFile(settingsProfile); + @Override + public IElementCacheConfiguration getElementCacheConfiguration() { + return elementCacheConfiguration; } -} \ No newline at end of file +} diff --git a/src/main/java/aquality/selenium/configuration/IConfiguration.java b/src/main/java/aquality/selenium/configuration/IConfiguration.java index 1f92fd3..3f4c9bc 100644 --- a/src/main/java/aquality/selenium/configuration/IConfiguration.java +++ b/src/main/java/aquality/selenium/configuration/IConfiguration.java @@ -1,5 +1,9 @@ package aquality.selenium.configuration; +import aquality.selenium.core.configurations.IElementCacheConfiguration; +import aquality.selenium.core.configurations.ILoggerConfiguration; +import aquality.selenium.core.configurations.IRetryConfiguration; + /** * Describes tool configuration. */ @@ -7,25 +11,36 @@ public interface IConfiguration { /** * Gets desired browser profile. + * * @return Profile of browser. */ IBrowserProfile getBrowserProfile(); /** * Gets configuration of timeouts. + * * @return Configuration of timeouts. */ ITimeoutConfiguration getTimeoutConfiguration(); /** * Gets configuration of retries. + * * @return Configuration of retries. */ IRetryConfiguration getRetryConfiguration(); /** * Gets configuration of logger. + * * @return Configuration of logger. */ ILoggerConfiguration getLoggerConfiguration(); + + /** + * Gets configuration of element caching. + * + * @return Configuration of element caching. + */ + IElementCacheConfiguration getElementCacheConfiguration(); } \ No newline at end of file diff --git a/src/main/java/aquality/selenium/configuration/IConfigurationsModule.java b/src/main/java/aquality/selenium/configuration/IConfigurationsModule.java new file mode 100644 index 0000000..90a50f9 --- /dev/null +++ b/src/main/java/aquality/selenium/configuration/IConfigurationsModule.java @@ -0,0 +1,29 @@ +package aquality.selenium.configuration; + +/** + * Describes implementations of configurations to be registered in DI container. + */ +public interface IConfigurationsModule extends aquality.selenium.core.configurations.IConfigurationsModule { + + /** + * @return class which implements {@link IBrowserProfile} + */ + default Class getBrowserProfileImplementation() { + return BrowserProfile.class; + } + + /** + * @return class which implements {@link ITimeoutConfiguration} + */ + @Override + default Class getTimeoutConfigurationImplementation() { + return TimeoutConfiguration.class; + } + + /** + * @return class which implements {@link IConfiguration} + */ + default Class getConfigurationImplementation() { + return Configuration.class; + } +} diff --git a/src/main/java/aquality/selenium/configuration/ILoggerConfiguration.java b/src/main/java/aquality/selenium/configuration/ILoggerConfiguration.java deleted file mode 100644 index e340dbc..0000000 --- a/src/main/java/aquality/selenium/configuration/ILoggerConfiguration.java +++ /dev/null @@ -1,15 +0,0 @@ -package aquality.selenium.configuration; - -import aquality.selenium.localization.SupportedLanguage; - -/** - * Describes logger configuration. - */ -public interface ILoggerConfiguration { - - /** - * Gets language which will be used for framework logger. - * @return Supported language. - */ - SupportedLanguage getLanguage(); -} diff --git a/src/main/java/aquality/selenium/configuration/IRetryConfiguration.java b/src/main/java/aquality/selenium/configuration/IRetryConfiguration.java deleted file mode 100644 index 6b7eccb..0000000 --- a/src/main/java/aquality/selenium/configuration/IRetryConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package aquality.selenium.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/configuration/ITimeoutConfiguration.java b/src/main/java/aquality/selenium/configuration/ITimeoutConfiguration.java index 1413e94..047a653 100644 --- a/src/main/java/aquality/selenium/configuration/ITimeoutConfiguration.java +++ b/src/main/java/aquality/selenium/configuration/ITimeoutConfiguration.java @@ -1,43 +1,23 @@ package aquality.selenium.configuration; +import java.time.Duration; + /** * Describes timeouts configuration. */ -public interface ITimeoutConfiguration { - - /** - * Gets WedDriver ImplicitWait timeout. - * @return ImplicitWait timeout. - */ - long getImplicit(); - - /** - * Gets default ConditionalWait timeout. - * @return ConditionalWait timeout. - */ - long getCondition(); +public interface ITimeoutConfiguration extends aquality.selenium.core.configurations.ITimeoutConfiguration { /** * Gets WedDriver AsynchronousJavaScript timeout. + * * @return AsynchronousJavaScript timeout. */ - long getScript(); + Duration getScript(); /** * Gets WedDriver PageLoad timeout. + * * @return PageLoad timeout. */ - long getPageLoad(); - - /** - * Gets ConditionalWait polling interval. - * @return ConditionalWait polling interval. - */ - long getPollingInterval(); - - /** - * Gets Command timeout. - * @return Command timeout. - */ - long getCommand(); + Duration getPageLoad(); } diff --git a/src/main/java/aquality/selenium/configuration/LoggerConfiguration.java b/src/main/java/aquality/selenium/configuration/LoggerConfiguration.java deleted file mode 100644 index f870002..0000000 --- a/src/main/java/aquality/selenium/configuration/LoggerConfiguration.java +++ /dev/null @@ -1,18 +0,0 @@ -package aquality.selenium.configuration; - -import aquality.selenium.localization.SupportedLanguage; -import aquality.selenium.utils.JsonFile; - -public class LoggerConfiguration implements ILoggerConfiguration{ - - private final JsonFile settingsFile; - - public LoggerConfiguration(JsonFile 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/configuration/RetryConfiguration.java b/src/main/java/aquality/selenium/configuration/RetryConfiguration.java deleted file mode 100644 index b9e240f..0000000 --- a/src/main/java/aquality/selenium/configuration/RetryConfiguration.java +++ /dev/null @@ -1,24 +0,0 @@ -package aquality.selenium.configuration; - -import aquality.selenium.utils.JsonFile; - -public class RetryConfiguration implements IRetryConfiguration { - private final int number; - private final long pollingInterval; - - - public RetryConfiguration(JsonFile 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/main/java/aquality/selenium/configuration/TimeoutConfiguration.java b/src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java index 8876d3a..b8857b4 100644 --- a/src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java +++ b/src/main/java/aquality/selenium/configuration/TimeoutConfiguration.java @@ -1,70 +1,49 @@ package aquality.selenium.configuration; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; -public class TimeoutConfiguration implements ITimeoutConfiguration{ - private final JsonFile settingsFile; +import java.time.Duration; - private final long condition; - private final long script; - private final long pageLoad; - private final long pollInterval; - private final long implicit; - private final long command; - - public TimeoutConfiguration(JsonFile settingsFile) { - this.settingsFile = settingsFile; - condition = getTimeout(TIMEOUT.CONDITION); - script = getTimeout(TIMEOUT.SCRIPT); - pageLoad = getTimeout(TIMEOUT.PAGE_LOAD); - pollInterval = getTimeout(TIMEOUT.POLL_INTERVAL); - implicit = getTimeout(TIMEOUT.IMPLICIT); - command = getTimeout(TIMEOUT.COMMAND); - } +public class TimeoutConfiguration extends aquality.selenium.core.configurations.TimeoutConfiguration + implements ITimeoutConfiguration { - private long getTimeout(TIMEOUT timeout){ - return Long.valueOf(settingsFile.getValue("/timeouts/" + timeout.getKey()).toString()); - } + private final ISettingsFile settingsFile; + private final Duration script; + private final Duration pageLoad; - - public long getImplicit(){ - return implicit; + @Inject + public TimeoutConfiguration(ISettingsFile settingsFile) { + super(settingsFile); + this.settingsFile = settingsFile; + script = getDurationFromSeconds(TIMEOUT.SCRIPT); + pageLoad = getDurationFromSeconds(TIMEOUT.PAGE_LOAD); } - public long getCondition(){ - return condition; + private Duration getDurationFromSeconds(TIMEOUT timeout) { + long seconds = Long.parseLong(settingsFile.getValue("/timeouts/" + timeout.getKey()).toString()); + return Duration.ofSeconds(seconds); } - public long getScript(){ + public Duration getScript() { return script; } - public long getPageLoad(){ + public Duration getPageLoad() { return pageLoad; } - public long getPollingInterval(){ - return pollInterval; - } - - public long getCommand(){ - return command; - } - private enum TIMEOUT { - IMPLICIT("timeoutImplicit"), - CONDITION("timeoutCondition"), SCRIPT("timeoutScript"), - PAGE_LOAD("timeoutPageLoad"), - POLL_INTERVAL("timeoutPollingInterval"), - COMMAND("timeoutCommand"); + PAGE_LOAD("timeoutPageLoad"); private String key; - TIMEOUT(String key){ + + TIMEOUT(String key) { this.key = key; } - private String getKey(){ + private String getKey() { return key; } } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java index 5eb5093..04dc360 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java @@ -1,7 +1,7 @@ package aquality.selenium.configuration.driversettings; import aquality.selenium.browser.BrowserName; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; import org.openqa.selenium.chrome.ChromeOptions; import java.util.HashMap; @@ -9,24 +9,24 @@ public class ChromeSettings extends DriverSettings { - private final JsonFile jsonFile; + private final ISettingsFile settingsFile; - public ChromeSettings(JsonFile jsonFile){ - this.jsonFile = jsonFile; + public ChromeSettings(ISettingsFile settingsFile){ + this.settingsFile = settingsFile; } @Override public ChromeOptions getCapabilities() { ChromeOptions chromeOptions = new ChromeOptions(); setChromePrefs(chromeOptions); - setCapabilities(chromeOptions, getBrowserName()); + setCapabilities(chromeOptions); setChromeArgs(chromeOptions); return chromeOptions; } private void setChromePrefs(ChromeOptions options){ HashMap chromePrefs = new HashMap<>(); - Map configOptions = getBrowserOptions(getBrowserName()); + Map configOptions = getBrowserOptions(); configOptions.forEach((key, value) -> { if (key.equals(getDownloadDirCapabilityKey())) { chromePrefs.put(key, getDownloadDir()); @@ -38,7 +38,8 @@ private void setChromePrefs(ChromeOptions options){ } private void setChromeArgs(ChromeOptions options) { - for (String arg : getBrowserStartArguments(getBrowserName())) { + logStartArguments(); + for (String arg : getBrowserStartArguments()) { options.addArguments(arg); } } @@ -49,8 +50,8 @@ public String getDownloadDirCapabilityKey() { } @Override - public JsonFile getSettingsFile() { - return jsonFile; + protected ISettingsFile getSettingsFile() { + return settingsFile; } @Override diff --git a/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java index 845c585..4efa913 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java @@ -1,8 +1,10 @@ package aquality.selenium.configuration.driversettings; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.BrowserName; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.logging.Logger; +import aquality.selenium.core.utilities.ISettingsFile; import org.openqa.selenium.MutableCapabilities; import java.io.File; @@ -12,61 +14,71 @@ abstract class DriverSettings implements IDriverSettings { - Map getBrowserOptions(BrowserName browserName) { - return getSettingsFile().getMap(getDriverSettingsPath(browserName, CapabilityType.OPTIONS)); + abstract ISettingsFile getSettingsFile(); + + Map getBrowserOptions() { + return getSettingsFile().getMap(getDriverSettingsPath(CapabilityType.OPTIONS)); + } + + private Map getBrowserCapabilities() { + return getSettingsFile().getMap(getDriverSettingsPath(CapabilityType.CAPABILITIES)); } - private Map getBrowserCapabilities(BrowserName browserName) { - return getSettingsFile().getMap(getDriverSettingsPath(browserName, CapabilityType.CAPABILITIES)); + List getBrowserStartArguments() { + return getSettingsFile().getList(getDriverSettingsPath(CapabilityType.START_ARGS)); } - List getBrowserStartArguments(BrowserName browserName) { - return getSettingsFile().getList(getDriverSettingsPath(browserName, CapabilityType.START_ARGS)); + void logStartArguments() { + List startArguments = getBrowserStartArguments(); + if (!startArguments.isEmpty()) { + AqualityServices.getLocalizedLogger() + .info("loc.browser.arguments.setting", String.join(" ", startArguments)); + } } @Override public String getWebDriverVersion() { - return String.valueOf(getSettingsFile().getValue(getDriverSettingsPath(getBrowserName()) + "/webDriverVersion")); + return String.valueOf(getSettingsFile().getValueOrDefault( + getDriverSettingsPath(getBrowserName()) + "/webDriverVersion", "Latest")); } @Override public String getSystemArchitecture() { - return String.valueOf(getSettingsFile().getValue(getDriverSettingsPath(getBrowserName()) + "/systemArchitecture")); + return String.valueOf(getSettingsFile().getValueOrDefault( + getDriverSettingsPath(getBrowserName()) + "/systemArchitecture", "Auto")); } - private String getDriverSettingsPath(BrowserName browserName, CapabilityType capabilityType){ - return getDriverSettingsPath(browserName) + "/" + capabilityType.getKey(); + private String getDriverSettingsPath(CapabilityType capabilityType) { + return getDriverSettingsPath(getBrowserName()) + "/" + capabilityType.getKey(); } - protected String getDriverSettingsPath(BrowserName browserName){ + String getDriverSettingsPath(BrowserName browserName) { return String.format("/driverSettings/%1$s", browserName.toString().toLowerCase()); } - void setCapabilities(MutableCapabilities options, BrowserName browserName){ - Map capabilities = getBrowserCapabilities(browserName); + void setCapabilities(MutableCapabilities options) { + Map capabilities = getBrowserCapabilities(); capabilities.forEach(options::setCapability); } + @Override public String getDownloadDir() { - return getDownloadDirectory(getBrowserName()); - } - - String getDownloadDirectory(BrowserName browserName) { - Map options = getBrowserOptions(browserName); + Map options = getBrowserOptions(); String key = getDownloadDirCapabilityKey(); - if(options.containsKey(key)){ + if (options.containsKey(key)) { String pathInConfiguration = String.valueOf(options.get(key)); return pathInConfiguration.contains(".") ? getAbsolutePath(pathInConfiguration) : pathInConfiguration; } - throw new IllegalArgumentException(String.format("failed to find %s profiles option for %s", key, browserName)); + throw new IllegalArgumentException(String.format("failed to find %s profiles option for %s", key, getBrowserName())); } private enum CapabilityType { - CAPABILITIES("capabilities"),OPTIONS("options"),START_ARGS("startArguments"); + CAPABILITIES("capabilities"), OPTIONS("options"), START_ARGS("startArguments"); private String key; - CapabilityType(String key){ + + CapabilityType(String key) { this.key = key; } @@ -79,13 +91,14 @@ private String getAbsolutePath(String path) { try { return new File(path).getCanonicalPath(); } catch (IOException e) { - String message = String.format(LocalizationManager.getInstance().getValue("loc.file.reading_exception"), path); + String message = String.format(AqualityServices.get(ILocalizationManager.class) + .getLocalizedMessage("loc.file.reading_exception"), path); getLogger().fatal(message, e); throw new IllegalArgumentException(message); } } - private Logger getLogger(){ + private Logger getLogger() { return Logger.getInstance(); } } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/EdgeSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/EdgeSettings.java index a7d1a9e..bf3fd84 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/EdgeSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/EdgeSettings.java @@ -1,29 +1,24 @@ package aquality.selenium.configuration.driversettings; import aquality.selenium.browser.BrowserName; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; import org.openqa.selenium.edge.EdgeOptions; public class EdgeSettings extends DriverSettings { - private final JsonFile jsonFile; + private final ISettingsFile settingsFile; - public EdgeSettings(JsonFile jsonFile){ - this.jsonFile = jsonFile; + public EdgeSettings(ISettingsFile settingsFile){ + this.settingsFile = settingsFile; } @Override public EdgeOptions getCapabilities() { EdgeOptions edgeOptions = new EdgeOptions(); - setCapabilities(edgeOptions, getBrowserName()); + setCapabilities(edgeOptions); return edgeOptions; } - @Override - public String getDownloadDir() { - return getDownloadDirectory(getBrowserName()); - } - @Override public String getDownloadDirCapabilityKey() { throw new IllegalArgumentException("Download directory for EDGE profiles is not supported"); @@ -35,7 +30,7 @@ public BrowserName getBrowserName() { } @Override - public JsonFile getSettingsFile() { - return jsonFile; + protected ISettingsFile getSettingsFile() { + return settingsFile; } } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java index 46b1720..9111fbb 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java @@ -1,23 +1,23 @@ package aquality.selenium.configuration.driversettings; import aquality.selenium.browser.BrowserName; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; import org.openqa.selenium.firefox.FirefoxOptions; import java.util.Map; public class FirefoxSettings extends DriverSettings { - private final JsonFile jsonFile; + private final ISettingsFile settingsFile; - public FirefoxSettings(JsonFile jsonFile){ - this.jsonFile = jsonFile; + public FirefoxSettings(ISettingsFile settingsFile){ + this.settingsFile = settingsFile; } @Override public FirefoxOptions getCapabilities() { FirefoxOptions firefoxOptions = new FirefoxOptions(); - setCapabilities(firefoxOptions, getBrowserName()); + setCapabilities(firefoxOptions); setFirefoxPrefs(firefoxOptions); setFirefoxArgs(firefoxOptions); return firefoxOptions; @@ -34,12 +34,12 @@ public BrowserName getBrowserName() { } @Override - public JsonFile getSettingsFile() { - return jsonFile; + protected ISettingsFile getSettingsFile() { + return settingsFile; } private void setFirefoxPrefs(FirefoxOptions options) { - Map configOptions = getBrowserOptions(getBrowserName()); + Map configOptions = getBrowserOptions(); configOptions.forEach((key, value) -> { if (key.equals(getDownloadDirCapabilityKey())) { options.addPreference(key, getDownloadDir()); @@ -55,7 +55,8 @@ else if (value instanceof Integer) { } private void setFirefoxArgs(FirefoxOptions options) { - for (String arg : getBrowserStartArguments(getBrowserName())) { + logStartArguments(); + for (String arg : getBrowserStartArguments()) { options.addArguments(arg); } } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/IDriverSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/IDriverSettings.java index c282cc2..c053dad 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/IDriverSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/IDriverSettings.java @@ -1,7 +1,6 @@ package aquality.selenium.configuration.driversettings; import aquality.selenium.browser.BrowserName; -import aquality.selenium.utils.JsonFile; import org.openqa.selenium.Capabilities; /** @@ -44,11 +43,4 @@ public interface IDriverSettings { * @return Browser name */ BrowserName getBrowserName(); - - /** - * Gets desired json file. - * @return Json file. - */ - JsonFile getSettingsFile(); - } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java index a9fdcdf..bc7ee27 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java @@ -1,21 +1,21 @@ package aquality.selenium.configuration.driversettings; import aquality.selenium.browser.BrowserName; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; import org.openqa.selenium.ie.InternetExplorerOptions; public class IExplorerSettings extends DriverSettings { - private final JsonFile jsonFile; + private final ISettingsFile settingsFile; - public IExplorerSettings(JsonFile jsonFile){ - this.jsonFile = jsonFile; + public IExplorerSettings(ISettingsFile settingsFile){ + this.settingsFile = settingsFile; } @Override public InternetExplorerOptions getCapabilities() { InternetExplorerOptions internetExplorerOptions = new InternetExplorerOptions(); - setCapabilities(internetExplorerOptions, getBrowserName()); + setCapabilities(internetExplorerOptions); return internetExplorerOptions; } @@ -30,7 +30,7 @@ public BrowserName getBrowserName() { } @Override - public JsonFile getSettingsFile() { - return jsonFile; + protected ISettingsFile getSettingsFile() { + return settingsFile; } } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/SafariSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/SafariSettings.java index fdf6766..538cb23 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/SafariSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/SafariSettings.java @@ -1,21 +1,21 @@ package aquality.selenium.configuration.driversettings; import aquality.selenium.browser.BrowserName; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; import org.openqa.selenium.safari.SafariOptions; public class SafariSettings extends DriverSettings { - private final JsonFile jsonFile; + private final ISettingsFile settingsFile; - public SafariSettings(JsonFile jsonFile){ - this.jsonFile = jsonFile; + public SafariSettings(ISettingsFile settingsFile){ + this.settingsFile = settingsFile; } @Override public SafariOptions getCapabilities() { SafariOptions safariOptions = new SafariOptions(); - setCapabilities(safariOptions, getBrowserName()); + setCapabilities(safariOptions); return safariOptions; } @@ -25,7 +25,7 @@ public String getDownloadDirCapabilityKey() { } @Override - String getDownloadDirectory(BrowserName browserName) { + public String getDownloadDir() { return String.valueOf(getSettingsFile().getValue(getDriverSettingsPath(getBrowserName()) + "/downloadDir")); } @@ -35,7 +35,7 @@ public BrowserName getBrowserName() { } @Override - public JsonFile getSettingsFile() { - return jsonFile; + protected ISettingsFile getSettingsFile() { + return settingsFile; } } diff --git a/src/main/java/aquality/selenium/elements/Button.java b/src/main/java/aquality/selenium/elements/Button.java index d477f5b..d680ddf 100644 --- a/src/main/java/aquality/selenium/elements/Button.java +++ b/src/main/java/aquality/selenium/elements/Button.java @@ -1,5 +1,6 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.IButton; import org.openqa.selenium.By; @@ -13,6 +14,6 @@ protected Button(final By locator, final String name, final ElementState state) } protected String getElementType() { - return getLocManager().getValue("loc.button"); + return getLocalizationManager().getLocalizedMessage("loc.button"); } } diff --git a/src/main/java/aquality/selenium/elements/CheckBox.java b/src/main/java/aquality/selenium/elements/CheckBox.java index bb3ccfd..0ed4f8b 100644 --- a/src/main/java/aquality/selenium/elements/CheckBox.java +++ b/src/main/java/aquality/selenium/elements/CheckBox.java @@ -1,5 +1,6 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.actions.CheckBoxJsActions; import aquality.selenium.elements.interfaces.ICheckBox; import org.openqa.selenium.By; @@ -14,7 +15,7 @@ protected CheckBox(final By locator, final String name, final ElementState state } protected String getElementType() { - return getLocManager().getValue("loc.checkbox"); + return getLocalizationManager().getLocalizedMessage("loc.checkbox"); } @Override @@ -48,14 +49,14 @@ public CheckBoxJsActions getJsActions() { * @param state value (true/false) */ private void setState(boolean state) { - getLogger().info(String.format("%1$s '%2$s'", getLocManager().getValue("loc.setting.value"), state)); + logElementAction("loc.setting.value", state); if (state != getState()) { click(); } } private boolean getState() { - info(getLocManager().getValue("loc.checkbox.get.state")); + logElementAction("loc.checkbox.get.state"); return getElement().isSelected(); } } diff --git a/src/main/java/aquality/selenium/elements/ComboBox.java b/src/main/java/aquality/selenium/elements/ComboBox.java index b171403..ebb6a3f 100644 --- a/src/main/java/aquality/selenium/elements/ComboBox.java +++ b/src/main/java/aquality/selenium/elements/ComboBox.java @@ -1,9 +1,8 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.actions.ComboBoxJsActions; import aquality.selenium.elements.interfaces.IComboBox; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.utils.ElementActionRetrier; import org.openqa.selenium.By; import org.openqa.selenium.InvalidElementStateException; import org.openqa.selenium.WebElement; @@ -19,26 +18,26 @@ */ public class ComboBox extends Element implements IComboBox { - private static final String LOG_SELECTING_VALUE = LocalizationManager.getInstance().getValue("loc.selecting.value"); + private static final String LOG_SELECTING_VALUE = "loc.selecting.value"; protected ComboBox(final By locator, final String name, final ElementState state) { super(locator, name, state); } protected String getElementType() { - return getLocManager().getValue("loc.combobox"); + return getLocalizationManager().getLocalizedMessage("loc.combobox"); } @Override public void selectByIndex(int index) { - info(LOG_SELECTING_VALUE); - ElementActionRetrier.doWithRetry(() -> new Select(getElement()).selectByIndex(index)); + logElementAction(LOG_SELECTING_VALUE); + doWithRetry(() -> new Select(getElement()).selectByIndex(index)); } @Override public void selectByText(String value) { - getLogger().info(getLocManager().getValue("loc.combobox.select.by.text"), value); - ElementActionRetrier.doWithRetry(() -> new Select(getElement()).selectByVisibleText(value)); + logElementAction("loc.combobox.select.by.text", value); + doWithRetry(() -> new Select(getElement()).selectByVisibleText(value)); } @Override @@ -49,7 +48,7 @@ public void clickAndSelectByText(String value) { @Override public void selectByContainingText(String text) { - info(LOG_SELECTING_VALUE); + logElementAction(LOG_SELECTING_VALUE); selectOptionThatContains(WebElement::getText, Select::selectByVisibleText, text); @@ -57,14 +56,14 @@ public void selectByContainingText(String text) { @Override public void selectByContainingValue(String value) { - info(LOG_SELECTING_VALUE); + logElementAction(LOG_SELECTING_VALUE); selectOptionThatContains(element -> element.getAttribute(Attributes.VALUE.toString()), Select::selectByValue, value); } private void selectOptionThatContains(Function getValueFunc, BiConsumer selectFunc, String value){ - ElementActionRetrier.doWithRetry(() -> { + doWithRetry(() -> { Select select = new Select(getElement()); List elements = select.getOptions(); boolean isSelected = false; @@ -77,15 +76,16 @@ private void selectOptionThatContains(Function getValueFunc, } } if (!isSelected){ - throw new InvalidElementStateException(String.format(getLocManager().getValue("loc.combobox.impossible.to.select.contain.value.or.text"), value, getName())); + throw new InvalidElementStateException(String.format(getLocalizationManager().getLocalizedMessage( + "loc.combobox.impossible.to.select.contain.value.or.text"), value, getName())); } }); } @Override public void selectByValue(String value) { - info(LOG_SELECTING_VALUE); - ElementActionRetrier.doWithRetry(() -> new Select(getElement()).selectByValue(value)); + logElementAction(LOG_SELECTING_VALUE); + doWithRetry(() -> new Select(getElement()).selectByValue(value)); } @Override @@ -96,19 +96,19 @@ public void clickAndSelectByValue(String value) { @Override public String getSelectedValue() { - return ElementActionRetrier.doWithRetry( + return doWithRetry( () -> new Select(getElement()).getFirstSelectedOption().getAttribute(Attributes.VALUE.toString())); } @Override public String getSelectedText() { - return ElementActionRetrier.doWithRetry(() -> new Select(getElement()).getFirstSelectedOption().getText()); + return doWithRetry(() -> new Select(getElement()).getFirstSelectedOption().getText()); } @Override public List getValues() { - getLogger().info(getLocManager().getValue("loc.combobox.get.values")); - return ElementActionRetrier.doWithRetry(() -> + logElementAction("loc.combobox.get.values"); + return doWithRetry(() -> new Select(getElement()).getOptions() .stream() .map(option -> option.getAttribute(Attributes.VALUE.toString())) @@ -117,8 +117,8 @@ public List getValues() { @Override public List getTexts() { - getLogger().info(getLocManager().getValue("loc.combobox.get.texts")); - return ElementActionRetrier.doWithRetry(() -> + logElementAction("loc.combobox.get.texts"); + return doWithRetry(() -> new Select(getElement()).getOptions() .stream() .map(WebElement::getText) diff --git a/src/main/java/aquality/selenium/elements/DesiredState.java b/src/main/java/aquality/selenium/elements/DesiredState.java deleted file mode 100644 index 2184ad4..0000000 --- a/src/main/java/aquality/selenium/elements/DesiredState.java +++ /dev/null @@ -1,44 +0,0 @@ -package aquality.selenium.elements; - -import org.openqa.selenium.WebElement; - -import java.util.function.Predicate; - -class DesiredState { - - private final Predicate desiredStatePredicate; - private final String message; - private boolean isCatchingTimeoutException; - private boolean isThrowingNoSuchElementException; - - DesiredState(Predicate desiredStatePredicate, String message){ - this.desiredStatePredicate = desiredStatePredicate; - this.message = message; - } - - public Predicate getDesiredStatePredicate() { - return desiredStatePredicate; - } - - public String getMessage() { - return message; - } - - public DesiredState withCatchingTimeoutException(){ - this.isCatchingTimeoutException = true; - return this; - } - - public DesiredState withThrowingNoSuchElementException(){ - this.isThrowingNoSuchElementException = true; - return this; - } - - public boolean isCatchingInTimeoutException() { - return isCatchingTimeoutException; - } - - public boolean isThrowingNoSuchElementException() { - return isThrowingNoSuchElementException; - } -} diff --git a/src/main/java/aquality/selenium/elements/Element.java b/src/main/java/aquality/selenium/elements/Element.java index 142557c..4a491e0 100644 --- a/src/main/java/aquality/selenium/elements/Element.java +++ b/src/main/java/aquality/selenium/elements/Element.java @@ -1,49 +1,32 @@ package aquality.selenium.elements; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; import aquality.selenium.browser.JavaScript; -import aquality.selenium.configuration.Configuration; +import aquality.selenium.core.configurations.IElementCacheConfiguration; +import aquality.selenium.core.configurations.ITimeoutConfiguration; +import aquality.selenium.core.elements.CachedElementStateProvider; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.elements.interfaces.IElementStateProvider; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.localization.ILocalizedLogger; +import aquality.selenium.core.utilities.IElementActionRetrier; +import aquality.selenium.core.waitings.IConditionalWait; import aquality.selenium.elements.actions.JsActions; import aquality.selenium.elements.actions.MouseActions; import aquality.selenium.elements.interfaces.IElement; -import aquality.selenium.elements.interfaces.IElementStateProvider; -import aquality.selenium.elements.interfaces.IElementSupplier; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; -import aquality.selenium.utils.ElementActionRetrier; +import aquality.selenium.elements.interfaces.IElementFactory; import org.openqa.selenium.By; -import org.openqa.selenium.Keys; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.remote.RemoteWebElement; +import java.time.Duration; + /** * Abstract class, describing wrapper of WebElement. */ -public abstract class Element implements IElement { - private static final String LOG_DELIMITER = "::"; - private static final String LOG_CLICKING = "loc.clicking"; - - /** - * Name of element - */ - private final String name; - - /** - * Element state (DISPLAYED by default) - */ - private final ElementState state; - - /** - * Element locator - */ - private final By locator; - - /** - * Element state provider - */ - private final ElementStateProvider elementStateProvider; - +public abstract class Element extends aquality.selenium.core.elements.Element implements IElement { /** * The main constructor * @@ -52,61 +35,68 @@ public abstract class Element implements IElement { * @param stateOf desired ElementState */ protected Element(final By loc, final String nameOf, final ElementState stateOf) { - locator = loc; - name = nameOf; - state = stateOf; - elementStateProvider = new ElementStateProvider(locator); + super(loc, nameOf, stateOf); } @Override - public RemoteWebElement getElement() { - return getElement(getDefaultTimeout()); + protected Browser getApplication() { + return AqualityServices.getBrowser(); } @Override - public RemoteWebElement getElement(Long timeout) { - try { - return (RemoteWebElement) ElementFinder.getInstance().findElement(locator, timeout, getElementState()); - } catch (NoSuchElementException e) { - getLogger().error(e.getMessage()); - getLogger().debug("Page Source:\r\n" + getBrowser().getDriver().getPageSource()); - throw new NoSuchElementException( - String.format("element %s was not found in %d seconds in state %s by locator %s", - getName(), timeout, getElementState(), getLocator())); - } + protected IElementFactory getElementFactory() { + return AqualityServices.getElementFactory(); } @Override - public By getLocator() { - return locator; + protected IElementFinder getElementFinder() { + return AqualityServices.get(IElementFinder.class); } - ElementState getElementState() { - return state; + @Override + protected IElementCacheConfiguration getElementCacheConfiguration() { + return AqualityServices.get(IElementCacheConfiguration.class); } @Override - public String getName() { - return name; + protected IElementActionRetrier getElementActionRetrier() { + return AqualityServices.get(IElementActionRetrier.class); } - /** - * The method returns the element type (used for logging) - * - * @return Type of element - */ - protected abstract String getElementType(); + @Override + protected ILocalizedLogger getLocalizedLogger() { + return AqualityServices.getLocalizedLogger(); + } + + protected ILocalizationManager getLocalizationManager() { + return AqualityServices.get(ILocalizationManager.class); + } @Override - public void sendKeys(Keys key) { - ElementActionRetrier.doWithRetry(() -> getElement().sendKeys(key)); + protected IConditionalWait getConditionalWait() { + return AqualityServices.getConditionalWait(); + } + + @Override + public RemoteWebElement getElement(Duration timeout) { + try { + return super.getElement(timeout); + } catch (NoSuchElementException e) { + getLogger().error(e.getMessage()); + long timeoutInSeconds = timeout == null + ? AqualityServices.get(ITimeoutConfiguration.class).getCondition().getSeconds() + : timeout.getSeconds(); + throw new NoSuchElementException( + String.format("element %s was not found in %d seconds in state %s by locator %s", + getName(), timeoutInSeconds, getElementState(), getLocator())); + } } @Override public void click() { - info(getLocManager().getValue(LOG_CLICKING)); + logElementAction("loc.clicking"); getJsActions().highlightElement(); - ElementActionRetrier.doWithRetry(() -> getElement().click()); + doWithRetry(() -> getElement().click()); } @Override @@ -117,79 +107,46 @@ public void clickAndWait() { @Override public String getText() { - return getText(HighlightState.NOT_HIGHLIGHT); + return getText(HighlightState.DEFAULT); } @Override public String getText(HighlightState highlightState) { - info(getLocManager().getValue("loc.get.text")); - if(highlightState.equals(HighlightState.HIGHLIGHT)){ - getJsActions().highlightElement(); - } - return ElementActionRetrier.doWithRetry(() -> getElement().getText()); + logElementAction("loc.get.text"); + getJsActions().highlightElement(); + return doWithRetry(() -> getElement().getText()); } @Override public IElementStateProvider state() { - return elementStateProvider; + return getElementCacheConfiguration().isEnabled() + ? new CachedElementStateProvider(getLocator(), getConditionalWait(), getCache(), getLocalizedLogger()) + : new ElementStateProvider(getLocator(), getConditionalWait(), getElementFinder()); } @Override public String getAttribute(final String attr, HighlightState highlightState) { - info(String.format(getLocManager().getValue("loc.el.getattr"), attr)); - if (highlightState.equals(HighlightState.HIGHLIGHT)) { - getJsActions().highlightElement(); - } - return ElementActionRetrier.doWithRetry(() -> getElement().getAttribute(attr)); - } - - @Override - public String getAttribute(final String attr) { - return getAttribute(attr, HighlightState.NOT_HIGHLIGHT); + logElementAction("loc.el.getattr", attr); + getJsActions().highlightElement(); + return doWithRetry(() -> getElement().getAttribute(attr)); } @Override public String getCssValue(final String propertyName, HighlightState highlightState) { - info(String.format(getLocManager().getValue("loc.el.cssvalue"), propertyName)); - if (highlightState.equals(HighlightState.HIGHLIGHT)) { - getJsActions().highlightElement(); - } - return ElementActionRetrier.doWithRetry(() -> getElement().getCssValue(propertyName)); - } - - @Override - public String getCssValue(final String propertyName) { - return getCssValue(propertyName, HighlightState.NOT_HIGHLIGHT); + logElementAction("loc.el.cssvalue", propertyName); + getJsActions().highlightElement(); + return doWithRetry(() -> getElement().getCssValue(propertyName)); } @Override public void setInnerHtml(final String value) { click(); - info(String.format(getLocManager().getValue("loc.send.text"), value)); - getBrowser().executeScript(JavaScript.SET_INNER_HTML.getScript(), getElement(), value); - } - - @Override - public void focus() { - ElementActionRetrier.doWithRetry(() -> getBrowser().getDriver().getMouse().mouseMove(getElement().getCoordinates())); + logElementAction("loc.send.text", value); + getBrowser().executeScript(JavaScript.SET_INNER_HTML, getElement(), value); } private Browser getBrowser(){ - return BrowserManager.getBrowser(); - } - - /** - * Format message for logging of current element - * - * @param message Message to display in the log - * @return Formatted message (containing the name and type of item) - */ - private String formatLogMsg(final String message) { - return String.format("%1$s '%2$s' %3$s %4$s", getElementType(), getName(), LOG_DELIMITER, message); - } - - protected void info(final String message) { - getLogger().info(formatLogMsg(message)); + return AqualityServices.getBrowser(); } @Override @@ -203,29 +160,7 @@ public MouseActions getMouseActions() { } @Override - public T findChildElement(By childLoc, ElementType type, ElementState state) { - return new ElementFactory().findChildElement(this, childLoc, type, state); - } - - @Override - public T findChildElement(By childLoc, Class clazz, ElementState state) { - return new ElementFactory().findChildElement(this, childLoc, clazz, state); - } - - @Override - public T findChildElement(By childLoc, IElementSupplier supplier, ElementState state) { - return new ElementFactory().findChildElement(this, childLoc, supplier, state); - } - - protected Logger getLogger(){ - return Logger.getInstance(); - } - - protected LocalizationManager getLocManager(){ - return LocalizationManager.getInstance(); - } - - long getDefaultTimeout(){ - return Configuration.getInstance().getTimeoutConfiguration().getCondition(); + public T findChildElement(By childLoc, String name, ElementType elementType, ElementState state) { + return getElementFactory().findChildElement(this, childLoc, name, elementType, state); } } \ No newline at end of file diff --git a/src/main/java/aquality/selenium/elements/ElementFactory.java b/src/main/java/aquality/selenium/elements/ElementFactory.java index 776ce17..4a26eee 100644 --- a/src/main/java/aquality/selenium/elements/ElementFactory.java +++ b/src/main/java/aquality/selenium/elements/ElementFactory.java @@ -1,192 +1,51 @@ package aquality.selenium.elements; -import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.JavaScript; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.configuration.ITimeoutConfiguration; +import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.waitings.IConditionalWait; import aquality.selenium.elements.interfaces.*; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; -import aquality.selenium.waitings.ConditionalWait; +import com.google.inject.Inject; import org.openqa.selenium.By; import org.openqa.selenium.By.ByXPath; -import org.openqa.selenium.SearchContext; import org.openqa.selenium.WebElement; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; -public class ElementFactory implements IElementFactory { - private static final int XPATH_SUBSTRING_BEGIN_INDEX = 10; +public class ElementFactory extends aquality.selenium.core.elements.ElementFactory implements IElementFactory { - @Override - public IButton getButton(final By locator, final String name, final ElementState state){ - return new Button(locator, name, state); - } - - @Override - public ICheckBox getCheckBox(final By locator, final String name, final ElementState state) { - return new CheckBox(locator, name, state); - } - - @Override - public IComboBox getComboBox(final By locator, final String name, final ElementState state) { - return new ComboBox(locator, name, state); - } - - @Override - public ILabel getLabel(final By locator, final String name, final ElementState state) { - return new Label(locator, name, state); - } - - @Override - public ILink getLink(final By locator, final String name, final ElementState state) { - return new Link(locator, name, state); - } - - @Override - public IRadioButton getRadioButton(final By locator, final String name, final ElementState state) { - return new RadioButton(locator, name, state); - } - - @Override - public ITextBox getTextBox(final By locator, final String name, final ElementState state) { - return new TextBox(locator, name, state); - } - - @Override - public T getCustomElement(IElementSupplier supplier, By locator, String name, ElementState state) { - return supplier.get(locator, name, state); - } - - @Override - public T findChildElement(IElement parentElement, By childLoc, - Class clazz, ElementState state) { - return findChildElementCore(parentElement, childLoc, getDefaultElementSupplier(clazz), state); - } - - @Override - public T findChildElement(IElement parentElement, By childLoc, - IElementSupplier supplier, ElementState state) { - return findChildElementCore(parentElement, childLoc, supplier, state); - } - - @Override - public T findChildElement(IElement parentElement, By childLoc, ElementType type, - ElementState state) { - return findChildElement(parentElement, childLoc, type.getClazz(), state); - } - - @Override - public List findElements(By locator, IElementSupplier supplier, ElementsCount count, - ElementState state) { - return findElementsCore(locator, supplier, state, count); + @Inject + public ElementFactory(IConditionalWait conditionalWait, IElementFinder elementFinder, ILocalizationManager localizationManager) { + super(conditionalWait, elementFinder, localizationManager); } @Override - public List findElements(By locator, Class clazz, ElementState state, ElementsCount count) { - return findElementsCore(locator, getDefaultElementSupplier(clazz), state, count); + protected Map, Class> getElementTypesMap() { + Map, Class> typesMap = new HashMap<>(); + typesMap.put(IButton.class, Button.class); + typesMap.put(ICheckBox.class, CheckBox.class); + typesMap.put(IComboBox.class, ComboBox.class); + typesMap.put(ILabel.class, Label.class); + typesMap.put(ILink.class, Link.class); + typesMap.put(IRadioButton.class, RadioButton.class); + typesMap.put(ITextBox.class, TextBox.class); + return typesMap; } + /** + * Generates xpath locator for target element. + * + * @param multipleElementsLocator locator used to find elements. + * @param webElement target element. + * @param elementIndex index of target element. + * @return target element's locator + */ @Override - public List findElements(By locator, ElementType type, ElementState state, ElementsCount count) { - return findElements(locator, type.getClazz(), state, count); - } - - private List findElementsCore(By locator, IElementSupplier supplier, - ElementState state, ElementsCount count) { - List elements = new ArrayList<>(); - switch (count) { - case ZERO: - ConditionalWait.waitFor(driver -> driver.findElements(locator).stream() - .noneMatch(webElement -> state == ElementState.EXISTS_IN_ANY_STATE || webElement.isDisplayed()), - String.format(LocalizationManager.getInstance().getValue("loc.elements.found.but.should.not"), - locator.toString())); - break; - case MORE_THEN_ZERO: - ConditionalWait.waitFor(driver -> !driver.findElements(locator).isEmpty(), - String.format(LocalizationManager.getInstance().getValue("loc.no.elements.found.by.locator"), - locator.toString())); - break; - default: - throw new IllegalArgumentException("No such expected value:".concat(count.toString())); - } - - List webElements = ElementFinder.getInstance().findElements(locator, getTimeoutConfig().getCondition(), state); - int index = 1; - for (WebElement webElement : webElements) { - try { - String xPath = locator.getClass().equals(ByXPath.class) - ? String.format("(%s)[%d]", locator.toString().substring(XPATH_SUBSTRING_BEGIN_INDEX), index) - : (String) getBrowser().executeScript(JavaScript.GET_ELEMENT_XPATH, webElement); - T element = supplier.get(By.xpath(xPath), "element " + index, state); - elements.add(element); - ++index; - } catch (IllegalArgumentException e) { - Logger.getInstance().debug(e.getMessage()); - } - } - - return elements; - } - - private T findChildElementCore(IElement parentElement, By childLoc, - IElementSupplier supplier, ElementState state) { - String childXPath; - if(childLoc.getClass().equals(ByXPath.class)){ - By parentLoc = parentElement.getLocator(); - String parentXpath = extractXpath(parentLoc, getBrowser().getDriver()); - childXPath = childLoc.toString().substring(XPATH_SUBSTRING_BEGIN_INDEX); - childXPath = childXPath.startsWith(".") ? "/".concat(childXPath) : childXPath; - childXPath = String.format("%s%s", parentXpath, childXPath); - } else { - childXPath = extractXpath(childLoc, parentElement.getElement()); - } - - return supplier.get(By.xpath(childXPath), "Child element of ".concat(parentElement.getName()), state); - } - - private String extractXpath(By locator, SearchContext searchContext) { - if(locator.getClass().equals(ByXPath.class)) { - return locator.toString().substring(XPATH_SUBSTRING_BEGIN_INDEX); - } - - WebElement webElement = searchContext.findElements(locator).stream().findFirst() - .orElseThrow(() -> new IllegalArgumentException("Cannot create element by non-xpath locator." - .concat(locator.toString()) - .concat("Please ensure that element is currently on screen, or use xpath locators instead"))); - return (String) getBrowser().executeScript(JavaScript.GET_ELEMENT_XPATH, webElement); - } - - private IElementSupplier getDefaultElementSupplier(Class clazz) { - Type type = convertElementClassToType(clazz); - - return (locator, name, state) -> { - Constructor ctor; - try { - ctor = ((Class) type).getDeclaredConstructor(By.class, String.class, ElementState.class); - return (T) ctor.newInstance(locator, name, state); - } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { - Logger.getInstance().debug(e.getMessage()); - throw new IllegalArgumentException("Something went wrong during element casting"); - } - }; - } - - private Type convertElementClassToType(Class clazz){ - return clazz.isInterface() ? ElementType.getTypeByClass(clazz).getClazz() : clazz; - } - - private Browser getBrowser(){ - return BrowserManager.getBrowser(); - } - - private ITimeoutConfiguration getTimeoutConfig(){ - return Configuration.getInstance().getTimeoutConfiguration(); + protected By generateXpathLocator(By multipleElementsLocator, WebElement webElement, int elementIndex) { + return multipleElementsLocator.getClass().equals(ByXPath.class) + ? super.generateXpathLocator(multipleElementsLocator, webElement, elementIndex) + : By.xpath((String) AqualityServices.getBrowser().executeScript(JavaScript.GET_ELEMENT_XPATH, webElement)); } } - diff --git a/src/main/java/aquality/selenium/elements/ElementFinder.java b/src/main/java/aquality/selenium/elements/ElementFinder.java deleted file mode 100644 index 3dfc110..0000000 --- a/src/main/java/aquality/selenium/elements/ElementFinder.java +++ /dev/null @@ -1,137 +0,0 @@ -package aquality.selenium.elements; - -import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.configuration.ITimeoutConfiguration; -import aquality.selenium.elements.interfaces.IElementFinder; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; -import aquality.selenium.waitings.ConditionalWait; -import org.openqa.selenium.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -class ElementFinder implements IElementFinder { - private static final ThreadLocal instanceHolder = new ThreadLocal<>(); - - static ElementFinder getInstance() { - if(instanceHolder.get() == null){ - instanceHolder.set(new ElementFinder()); - } - return instanceHolder.get(); - } - - private ElementFinder(){ - } - - @Override - public long getDefaultTimeout() { - return getTimeoutConfiguration().getCondition(); - } - - @Override - public WebElement findElement(By locator, long timeout, ElementState state) { - List elements = findElements(locator, timeout, state); - if(!elements.isEmpty()){ - return elements.get(0); - }else { - String message = String.format( - "element was not found in %d seconds in state %s by locator %s", timeout, state, locator); - throw new NoSuchElementException(message); - } - } - - @Override - public List findElements(By locator, long timeout, ElementState state) { - switch (state) { - case DISPLAYED: - return findElements(locator, timeout, new DesiredState(WebElement::isDisplayed, String.format(getLocManager().getValue("loc.no.elements.found.in.state"), locator, "DISPLAYED", timeout)).withCatchingTimeoutException()); - case EXISTS_IN_ANY_STATE: - return findElements(locator, timeout, new DesiredState(Objects::nonNull, String.format(getLocManager().getValue("loc.no.elements.found.in.state"), locator, "EXIST", timeout)).withCatchingTimeoutException()); - default: - String errorMessage = String.format("'%s' state is not recognized", state.toString()); - throw new IllegalArgumentException(errorMessage); - } - } - - List findElements(By locator, long timeout, DesiredState desiredState) { - List foundElements = new ArrayList<>(); - List resultElements = new ArrayList<>(); - long zeroTimeout = 0L; - getBrowser().setImplicitWaitTimeout(zeroTimeout); - try { - ConditionalWait.waitFor(driver -> - { - List allFoundElements = driver.findElements(locator); - foundElements.addAll(allFoundElements); - List filteredElements = filterByState(allFoundElements, desiredState.getDesiredStatePredicate()); - resultElements.addAll(filteredElements); - return !filteredElements.isEmpty(); - }, timeout, getTimeoutConfiguration().getPollingInterval(), desiredState.getMessage()); - } catch (TimeoutException e) { - applyResult(locator, desiredState, foundElements); - } - getBrowser().setImplicitWaitTimeout(getTimeoutConfiguration().getImplicit()); - return resultElements; - } - - /** - * depends on configuration of DesiredState object it can be required to throw or not NoSuchElementException - * @param locator locator that is using to find elements - * @param desiredState DesiredState object - * @param foundElements list of all found elements by locator. - */ - private void applyResult(By locator, DesiredState desiredState, List foundElements){ - if (desiredState.isCatchingInTimeoutException()){ - if(foundElements.isEmpty()){ - String message = String.format(getLocManager().getValue("loc.no.elements.found.by.locator"), locator); - if(desiredState.isThrowingNoSuchElementException()){ - throw new NoSuchElementException(message); - } - getLogger().debug(message); - }else { - getLogger().debug(String.format(getLocManager().getValue("loc.elements.were.found.but.not.in.state"), locator, desiredState.getMessage())); - } - }else { - throw new TimeoutException(desiredState.getMessage()); - } - } - - /** - * tries to find list of elements in the DOM during defined timeout - * @param locator locator to find elements - * @param timeout timeout - * @return list of elements ot empty list if no elements found - */ - public List findElements(By locator, long timeout) { - return findElements(locator, timeout, ElementState.EXISTS_IN_ANY_STATE); - } - - private List filterByState(List foundElements, Predicate desiredElementState){ - List filteredElements = new ArrayList<>(); - if(!foundElements.isEmpty()){ - filteredElements.addAll(foundElements.stream().filter(desiredElementState).collect(Collectors.toList())); - } - return filteredElements; - } - - private Browser getBrowser() { - return BrowserManager.getBrowser(); - } - - private ITimeoutConfiguration getTimeoutConfiguration() { - return Configuration.getInstance().getTimeoutConfiguration(); - } - - private Logger getLogger(){ - return Logger.getInstance(); - } - - private LocalizationManager getLocManager(){ - return LocalizationManager.getInstance(); - } -} diff --git a/src/main/java/aquality/selenium/elements/ElementState.java b/src/main/java/aquality/selenium/elements/ElementState.java deleted file mode 100644 index 71f77e6..0000000 --- a/src/main/java/aquality/selenium/elements/ElementState.java +++ /dev/null @@ -1,17 +0,0 @@ -package aquality.selenium.elements; - -public enum ElementState { - DISPLAYED("displayed"), - EXISTS_IN_ANY_STATE("exists"); - - private final String state; - - ElementState(String state) { - this.state = state; - } - - @Override - public String toString() { - return state; - } -} diff --git a/src/main/java/aquality/selenium/elements/ElementStateProvider.java b/src/main/java/aquality/selenium/elements/ElementStateProvider.java index dee323c..561f88a 100644 --- a/src/main/java/aquality/selenium/elements/ElementStateProvider.java +++ b/src/main/java/aquality/selenium/elements/ElementStateProvider.java @@ -1,175 +1,73 @@ package aquality.selenium.elements; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.configuration.ITimeoutConfiguration; -import aquality.selenium.elements.interfaces.IElementStateProvider; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; -import aquality.selenium.waitings.ConditionalWait; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.elements.DefaultElementStateProvider; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.waitings.IConditionalWait; import org.openqa.selenium.By; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebElement; -import java.util.List; -import java.util.Objects; -class ElementStateProvider implements IElementStateProvider { +import java.time.Duration; - private static final long ZERO_TIMEOUT = 0L; +public class ElementStateProvider extends DefaultElementStateProvider { + + private static final String WAIT_FOR_STATE_KEY = "loc.waitinstate"; private final By locator; - ElementStateProvider(By locator) { + public ElementStateProvider(By locator, IConditionalWait conditionalWait, IElementFinder elementFinder) { + super(locator, conditionalWait, elementFinder); this.locator = locator; } - @Override - public boolean isClickable() { - return waitForClickable(ZERO_TIMEOUT); - } - - @Override - public boolean waitForClickable(long timeout) { - String stateName = "CLICKABLE"; - getLogger().info(String.format(getLocManager().getValue("loc.waitinstate"), stateName, getLocator())); - DesiredState desiredState = new DesiredState(element -> element.isDisplayed() && element.isEnabled(), getDesiredStateMessage(stateName, timeout)).withCatchingTimeoutException(); - return isElementInDesiredCondition(timeout, desiredState); - } - - @Override - public boolean waitForClickable() { - return waitForClickable(getDefaultTimeout()); - } - - @Override - public boolean isDisplayed() { - return waitForDisplayed(ZERO_TIMEOUT); - } - - @Override - public boolean waitForDisplayed(long timeout) { - getLogger().info(String.format(getLocManager().getValue("loc.waitinstate"), ElementState.DISPLAYED, getLocator())); - DesiredState desiredState = new DesiredState(WebElement::isDisplayed, getDesiredStateMessage("DISPLAYED", timeout)).withCatchingTimeoutException(); - return isElementInDesiredCondition(timeout, desiredState); - } - - @Override - public boolean waitForDisplayed() { - return waitForDisplayed(getDefaultTimeout()); - } - - @Override - public boolean waitForNotDisplayed(long timeout) { - getLogger().info(getLocManager().getValue("loc.waitinvisible")); - DesiredState desiredState = new DesiredState(element -> !element.isDisplayed(), getDesiredStateMessage("NOT DISPLAYED", timeout)).withCatchingTimeoutException(); - return isElementInDesiredCondition(timeout, desiredState); - } - - @Override - public boolean waitForNotDisplayed() { - return waitForNotDisplayed(getDefaultTimeout()); + private void logLocInfo(String key, Object... args) { + AqualityServices.getLocalizedLogger().info(key, args); } @Override - public boolean isExist() { - return waitForExist(ZERO_TIMEOUT); + protected boolean isElementEnabled(WebElement element) { + return element.isEnabled() && !element.getAttribute(Attributes.CLASS.toString()).contains("disabled"); } @Override - public boolean waitForExist(long timeout) { - getLogger().info(getLocManager().getValue("loc.waitexists")); - DesiredState desiredState = new DesiredState(Objects::nonNull, getDesiredStateMessage("EXIST", timeout)).withCatchingTimeoutException(); - return isElementInDesiredCondition(timeout, desiredState); + public void waitForClickable(Duration timeout) { + logLocInfo(WAIT_FOR_STATE_KEY, elementClickable().getStateName(), locator); + super.waitForClickable(timeout); } @Override - public boolean waitForExist() { - return waitForExist(getDefaultTimeout()); + public boolean waitForDisplayed(Duration timeout) { + logLocInfo(WAIT_FOR_STATE_KEY, ElementState.DISPLAYED, locator); + return super.waitForDisplayed(timeout); } @Override - public boolean waitForNotExist(long timeout) { - String message = String.format(getLocManager().getValue("loc.waitnotexists"), timeout); - getLogger().info(message); - try{ - long zeroTimeout = 0L; - return ConditionalWait.waitFor(y -> findElements(zeroTimeout).isEmpty(), - timeout, - getTimeoutConfiguration().getPollingInterval(), - message); - }catch (TimeoutException e){ - getLogger().debug(getDesiredStateMessage("NOT EXIST", timeout)); - return false; - }catch (NoSuchElementException e){ - return true; - } + public boolean waitForNotDisplayed(Duration timeout) { + logLocInfo("loc.waitinvisible", locator); + return super.waitForNotDisplayed(timeout); } @Override - public boolean waitForNotExist() { - return waitForNotExist(getDefaultTimeout()); + public boolean waitForExist(Duration timeout) { + logLocInfo("loc.waitexists", locator); + return super.waitForExist(timeout); } @Override - public boolean isEnabled() { - return waitForEnabled(ZERO_TIMEOUT); + public boolean waitForNotExist(Duration timeout) { + logLocInfo("loc.waitnotexists", locator); + return super.waitForNotExist(timeout); } @Override - public boolean waitForEnabled(long timeout) { - DesiredState desiredState = new DesiredState(y -> - findElements(timeout). - stream().anyMatch(element -> - element.isEnabled() && - !element.getAttribute(Attributes.CLASS.toString()).contains("disabled") - ), getDesiredStateMessage("ENABLED", timeout)).withCatchingTimeoutException().withThrowingNoSuchElementException(); - return isElementInDesiredCondition(timeout, desiredState); + public boolean waitForEnabled(Duration timeout) { + logLocInfo(WAIT_FOR_STATE_KEY, elementEnabled().getStateName(), locator); + return super.waitForEnabled(timeout); } @Override - public boolean waitForEnabled() { - return waitForEnabled(getDefaultTimeout()); - } - - @Override - public boolean waitForNotEnabled(long timeout) { - DesiredState desiredState = new DesiredState(driver -> !isEnabled(), getDesiredStateMessage("NOT ENABLED", timeout)).withCatchingTimeoutException().withThrowingNoSuchElementException(); - return isElementInDesiredCondition(timeout, desiredState); - } - - @Override - public boolean waitForNotEnabled() { - return waitForNotEnabled(getDefaultTimeout()); - } - - private List findElements(long timeout) { - return ElementFinder.getInstance().findElements(getLocator(), timeout, ElementState.EXISTS_IN_ANY_STATE); - } - - private By getLocator() { - return locator; - } - - private boolean isElementInDesiredCondition(long timeout, DesiredState desiredState){ - return !ElementFinder.getInstance().findElements(locator, timeout, desiredState).isEmpty(); - } - - private Logger getLogger(){ - return Logger.getInstance(); - } - - private LocalizationManager getLocManager(){ - return LocalizationManager.getInstance(); - } - - private long getDefaultTimeout(){ - return getTimeoutConfiguration().getCondition(); - } - - private ITimeoutConfiguration getTimeoutConfiguration(){ - return Configuration.getInstance().getTimeoutConfiguration(); - } - - private String getDesiredStateMessage(String desiredStateName, long timeout){ - return String.format(getLocManager().getValue("loc.no.elements.found.in.state"), locator, desiredStateName, timeout); + public boolean waitForNotEnabled(Duration timeout) { + logLocInfo(WAIT_FOR_STATE_KEY, elementNotEnabled().getStateName(), locator); + return super.waitForNotEnabled(timeout); } } diff --git a/src/main/java/aquality/selenium/elements/ElementType.java b/src/main/java/aquality/selenium/elements/ElementType.java index b9108a0..2709ef4 100644 --- a/src/main/java/aquality/selenium/elements/ElementType.java +++ b/src/main/java/aquality/selenium/elements/ElementType.java @@ -1,17 +1,15 @@ package aquality.selenium.elements; -import aquality.selenium.elements.interfaces.IElement; - -import java.util.Arrays; +import aquality.selenium.elements.interfaces.*; public enum ElementType { - BUTTON(Button.class), - CHECKBOX(CheckBox.class), - COMBOBOX(ComboBox.class), - LABEL(Label.class), - LINK(Link.class), - RADIOBUTTON(RadioButton.class), - TEXTBOX(TextBox.class); + BUTTON(IButton.class), + CHECKBOX(ICheckBox.class), + COMBOBOX(IComboBox.class), + LABEL(ILabel.class), + LINK(ILink.class), + RADIOBUTTON(IRadioButton.class), + TEXTBOX(ITextBox.class); private Class clazz; @@ -19,12 +17,7 @@ ElementType(Class clazz){ this.clazz = clazz; } - Class getClazz() { - return clazz; - } - - static ElementType getTypeByClass(Class clazz){ - return Arrays.stream(values()).filter(elementType -> clazz.isAssignableFrom(elementType.getClazz())).findAny() - .orElseThrow(IllegalArgumentException::new); + public Class getClazz() { + return (Class) clazz; } } diff --git a/src/main/java/aquality/selenium/elements/ElementsCount.java b/src/main/java/aquality/selenium/elements/ElementsCount.java deleted file mode 100644 index fc1bc1a..0000000 --- a/src/main/java/aquality/selenium/elements/ElementsCount.java +++ /dev/null @@ -1,6 +0,0 @@ -package aquality.selenium.elements; - -public enum ElementsCount { - ZERO, - MORE_THEN_ZERO -} diff --git a/src/main/java/aquality/selenium/elements/HighlightState.java b/src/main/java/aquality/selenium/elements/HighlightState.java index c019034..2fc8e36 100644 --- a/src/main/java/aquality/selenium/elements/HighlightState.java +++ b/src/main/java/aquality/selenium/elements/HighlightState.java @@ -1,17 +1,12 @@ package aquality.selenium.elements; public enum HighlightState { - HIGHLIGHT("highlight"), - NOT_HIGHLIGHT("not_highlight"); - - private final String state; - - HighlightState(String state) { - this.state = state; - } + DEFAULT, + HIGHLIGHT, + NOT_HIGHLIGHT; @Override public String toString() { - return state; + return name().toLowerCase(); } } diff --git a/src/main/java/aquality/selenium/elements/IElementsModule.java b/src/main/java/aquality/selenium/elements/IElementsModule.java new file mode 100644 index 0000000..36641e6 --- /dev/null +++ b/src/main/java/aquality/selenium/elements/IElementsModule.java @@ -0,0 +1,16 @@ +package aquality.selenium.elements; + +import aquality.selenium.elements.interfaces.IElementFactory; + +/** + * Describes implementations of elements services to be registered in DI container. + */ +public interface IElementsModule extends aquality.selenium.core.elements.IElementsModule { + /** + * @return class which implements {@link IElementFactory} + */ + @Override + default Class getElementFactoryImplementation() { + return ElementFactory.class; + } +} diff --git a/src/main/java/aquality/selenium/elements/Label.java b/src/main/java/aquality/selenium/elements/Label.java index 43d78f4..655d34b 100644 --- a/src/main/java/aquality/selenium/elements/Label.java +++ b/src/main/java/aquality/selenium/elements/Label.java @@ -1,5 +1,6 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.ILabel; import org.openqa.selenium.By; @@ -10,7 +11,7 @@ protected Label(final By locator, final String name, final ElementState state) { } protected String getElementType() { - return getLocManager().getValue("loc.label"); + return getLocalizationManager().getLocalizedMessage("loc.label"); } } diff --git a/src/main/java/aquality/selenium/elements/Link.java b/src/main/java/aquality/selenium/elements/Link.java index 79abf54..eadeafb 100644 --- a/src/main/java/aquality/selenium/elements/Link.java +++ b/src/main/java/aquality/selenium/elements/Link.java @@ -1,5 +1,6 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.ILink; import org.openqa.selenium.By; @@ -13,7 +14,7 @@ protected Link(final By locator, final String name, final ElementState state) { } protected String getElementType() { - return getLocManager().getValue("loc.link"); + return getLocalizationManager().getLocalizedMessage("loc.link"); } @Override diff --git a/src/main/java/aquality/selenium/elements/RadioButton.java b/src/main/java/aquality/selenium/elements/RadioButton.java index 1c484a5..8a0b4a0 100644 --- a/src/main/java/aquality/selenium/elements/RadioButton.java +++ b/src/main/java/aquality/selenium/elements/RadioButton.java @@ -1,5 +1,6 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.IRadioButton; import org.openqa.selenium.By; @@ -13,6 +14,11 @@ protected RadioButton(final By locator, final String name, final ElementState st } protected String getElementType() { - return getLocManager().getValue("loc.radio"); + return getLocalizationManager().getLocalizedMessage("loc.radio"); + } + + @Override + public boolean isChecked() { + return doWithRetry(() -> getElement().isSelected()); } } diff --git a/src/main/java/aquality/selenium/elements/TextBox.java b/src/main/java/aquality/selenium/elements/TextBox.java index 914aa89..73708cb 100644 --- a/src/main/java/aquality/selenium/elements/TextBox.java +++ b/src/main/java/aquality/selenium/elements/TextBox.java @@ -1,8 +1,7 @@ package aquality.selenium.elements; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.ITextBox; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.utils.ElementActionRetrier; import org.openqa.selenium.By; import org.openqa.selenium.Keys; @@ -11,17 +10,17 @@ */ public class TextBox extends Element implements ITextBox { - private final String logTyping = getLocManager().getValue("loc.text.typing"); - private final String logClearing = getLocManager().getValue("loc.text.clearing"); - private final String logSendingKeys = getLocManager().getValue("loc.text.sending.keys"); - private final String logMaskedValue = getLocManager().getValue("loc.text.masked_value"); + private static final String LOG_TYPING = "loc.text.typing"; + private static final String LOG_CLEARING = "loc.text.clearing"; + private static final String LOG_SENDING_KEYS = "loc.text.sending.keys"; + private static final String LOG_MASKED_VALUE = "loc.text.masked_value"; protected TextBox(final By locator, final String name, final ElementState state) { super(locator, name, state); } protected String getElementType() { - return LocalizationManager.getInstance().getValue("loc.text.field"); + return getLocalizationManager().getLocalizedMessage("loc.text.field"); } @Override @@ -36,7 +35,7 @@ public void typeSecret(final String value) { @Override public void sendKeys(final Keys keys) { - info(String.format(logSendingKeys, keys.toString())); + logElementAction(LOG_SENDING_KEYS, keys.toString()); super.sendKeys(keys); } @@ -52,7 +51,7 @@ public void clearAndTypeSecret(final String value) { @Override public void submit() { - ElementActionRetrier.doWithRetry(() -> getElement().submit()); + doWithRetry(() -> getElement().submit()); } @Override @@ -62,26 +61,25 @@ public String getValue() { @Override public void focus() { - ElementActionRetrier.doWithRetry(() -> getElement().sendKeys("")); + doWithRetry(() -> getElement().sendKeys("")); } @Override public void unfocus() { - ElementActionRetrier.doWithRetry(() -> getElement().sendKeys(Keys.TAB)); + doWithRetry(() -> getElement().sendKeys(Keys.TAB)); } private void type(final String value, final boolean maskValueInLog) { - info(String.format(logTyping, maskValueInLog ? logMaskedValue : value)); + logElementAction(LOG_TYPING, maskValueInLog ? LOG_MASKED_VALUE : value); getJsActions().highlightElement(); - ElementActionRetrier.doWithRetry(() -> getElement().sendKeys(value)); + doWithRetry(() -> getElement().sendKeys(value)); } private void clearAndType(final String value, final boolean maskValueInLog) { + logElementAction(LOG_CLEARING); + logElementAction(LOG_TYPING, maskValueInLog ? LOG_MASKED_VALUE : value); getJsActions().highlightElement(); - info(logClearing); - info(String.format(logTyping, maskValueInLog ? logMaskedValue : value)); - getJsActions().highlightElement(); - ElementActionRetrier.doWithRetry(() -> { + doWithRetry(() -> { getElement().clear(); getElement().sendKeys(value); }); diff --git a/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java b/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java index 14fa624..82e9412 100644 --- a/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java +++ b/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java @@ -16,7 +16,7 @@ public CheckBoxJsActions(ICheckBox checkBox, String elementType) { * @return state of checkbox using .checked property of element */ public boolean getState() { - infoLoc("loc.checkbox.get.state"); + logElementAction("loc.checkbox.get.state"); return Boolean.valueOf(executeScript(JavaScript.GET_CHECKBOX_STATE, element).toString()); } @@ -55,7 +55,7 @@ public void toggle() { * @param state value (true/false) */ private void setState(boolean state) { - infoLoc(String.format("%1$s '%2$s'", localizationManager.getValue("loc.setting.value"), state)); + logElementAction("loc.setting.value", state); if (state != getState()) { click(); } diff --git a/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java b/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java index 9e1a250..78682e8 100644 --- a/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java +++ b/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java @@ -17,6 +17,7 @@ public ComboBoxJsActions(IComboBox comboBox, String elementType) { * @return texts of options from ComboBox */ public List getTexts() { + logElementAction("loc.combobox.get.texts.js"); return (List) executeScript(JavaScript.GET_COMBOBOX_TEXTS, element); } @@ -26,6 +27,7 @@ public List getTexts() { * @return text of selected element */ public String getSelectedText() { + logElementAction("loc.combobox.get.text.js"); return (String) executeScript(JavaScript.GET_COMBOBOX_SELECTED_TEXT, element); } @@ -35,6 +37,7 @@ public String getSelectedText() { * @param text target option */ public void selectValueByText(final String text) { + logElementAction("loc.combobox.select.by.text.js", text); executeScript(JavaScript.SELECT_COMBOBOX_VALUE_BY_TEXT, element, text); } } \ No newline at end of file diff --git a/src/main/java/aquality/selenium/elements/actions/JsActions.java b/src/main/java/aquality/selenium/elements/actions/JsActions.java index e6306d2..3a916ff 100644 --- a/src/main/java/aquality/selenium/elements/actions/JsActions.java +++ b/src/main/java/aquality/selenium/elements/actions/JsActions.java @@ -1,22 +1,16 @@ package aquality.selenium.elements.actions; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; import aquality.selenium.browser.JavaScript; -import aquality.selenium.configuration.Configuration; +import aquality.selenium.elements.HighlightState; import aquality.selenium.elements.interfaces.IElement; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; import org.openqa.selenium.Point; import java.util.ArrayList; public class JsActions { - private static final Configuration configuration = Configuration.getInstance(); - private static final String LOG_DELIMITER = "::"; - protected final Logger logger = Logger.getInstance(); - protected final LocalizationManager localizationManager = LocalizationManager.getInstance(); protected IElement element; protected String type; protected String name; @@ -32,7 +26,7 @@ public JsActions(IElement element, String type) { * Click via JS. */ public void click() { - infoLoc("loc.clicking.js"); + logElementAction("loc.clicking.js"); highlightElement(); executeScript(JavaScript.CLICK_ELEMENT, element); } @@ -49,7 +43,14 @@ public void clickAndWait() { * Highlights the element */ public void highlightElement() { - if (configuration.getBrowserProfile().isElementHighlightEnabled()) { + highlightElement(HighlightState.DEFAULT); + } + + /** + * Highlights the element. + */ + public void highlightElement(HighlightState highlightState) { + if (AqualityServices.getBrowserProfile().isElementHighlightEnabled() || highlightState.equals(HighlightState.HIGHLIGHT)) { executeScript(JavaScript.BORDER_ELEMENT, element); } } @@ -58,17 +59,18 @@ public void highlightElement() { * Scrolling to element */ public void scrollIntoView() { - infoLoc("loc.scrolling.js"); + logElementAction("loc.scrolling.js"); executeScript(JavaScript.SCROLL_TO_ELEMENT, element, true); } /** * Scrolling by coordinates + * * @param x horizontal coordinate * @param y vertical coordinate */ public void scrollBy(int x, int y) { - infoLoc("loc.scrolling.js"); + logElementAction("loc.scrolling.js"); executeScript(JavaScript.SCROLL_BY, element, x, y); } @@ -76,7 +78,7 @@ public void scrollBy(int x, int y) { * Scrolling to element's center */ public void scrollToTheCenter() { - infoLoc("loc.scrolling.center.js"); + logElementAction("loc.scrolling.center.js"); executeScript(JavaScript.SCROLL_TO_ELEMENT_CENTER, element); } @@ -86,7 +88,7 @@ public void scrollToTheCenter() { * @param value Value */ public void setValue(final String value) { - infoLoc("loc.setting.value"); + logElementAction("loc.setting.value", value); executeScript(JavaScript.SET_VALUE, element, value); } @@ -94,16 +96,17 @@ public void setValue(final String value) { * Focusing element */ public void setFocus() { - infoLoc("loc.focusing"); + logElementAction("loc.focusing"); executeScript(JavaScript.SET_FOCUS, element); } /** * Checking if element presented on screen + * * @return true if is on screen, false otherwise */ public boolean isElementOnScreen() { - infoLoc("loc.is.present.js"); + logElementAction("loc.is.present.js"); return (boolean) executeScript(JavaScript.ELEMENT_IS_ON_SCREEN, element); } @@ -113,7 +116,7 @@ public boolean isElementOnScreen() { * @return element's text */ public String getElementText() { - infoLoc("loc.get.text.js"); + logElementAction("loc.get.text.js"); return (String) executeScript(JavaScript.GET_ELEMENT_TEXT, element); } @@ -121,12 +124,13 @@ public String getElementText() { * Hover mouse over element */ public void hoverMouse() { - infoLoc("loc.hover.js"); + logElementAction("loc.hover.js"); executeScript(JavaScript.MOUSE_HOVER, element); } /** * Gets element coordinates relative to the View Port + * * @return Point object */ public Point getViewPortCoordinates() { @@ -136,35 +140,32 @@ public Point getViewPortCoordinates() { /** * Gets element's XPath + * * @return element's XPath locator */ public String getXPath() { + logElementAction("loc.get.xpath.js"); return (String) executeScript(JavaScript.GET_ELEMENT_XPATH, element); } - protected Object executeScript(JavaScript javaScript, IElement element){ + protected Object executeScript(JavaScript javaScript, IElement element) { return getBrowser().executeScript(javaScript, element.getElement()); } - protected Object executeScript(JavaScript javaScript, IElement element, Object... args){ + protected Object executeScript(JavaScript javaScript, IElement element, Object... args) { return getBrowser().executeScript(javaScript, element.getElement(), args); } /** * The implementation of a method for logging of Javascript actions * - * @param message Message to display in the log - * @return Formatted message (containing the name and type of item) + * @param key key in localization resource of message to display in the log. */ - private String formatJsActionMessage(final String message) { - return String.format("%1$s '%2$s' %3$s %4$s", type, name, LOG_DELIMITER, message); - } - - protected void infoLoc(String key) { - logger.info(formatJsActionMessage(localizationManager.getValue(key))); + protected void logElementAction(String key, Object... args) { + AqualityServices.getLocalizedLogger().infoElementAction(type, name, key, args); } - private Browser getBrowser(){ - return BrowserManager.getBrowser(); + private Browser getBrowser() { + return AqualityServices.getBrowser(); } } diff --git a/src/main/java/aquality/selenium/elements/actions/MouseActions.java b/src/main/java/aquality/selenium/elements/actions/MouseActions.java index 67e48cf..9ea0d7f 100644 --- a/src/main/java/aquality/selenium/elements/actions/MouseActions.java +++ b/src/main/java/aquality/selenium/elements/actions/MouseActions.java @@ -1,20 +1,15 @@ package aquality.selenium.elements.actions; - +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.core.utilities.IElementActionRetrier; import aquality.selenium.elements.interfaces.IElement; -import aquality.selenium.localization.LocalizationManager; -import aquality.selenium.logger.Logger; -import aquality.selenium.utils.ElementActionRetrier; import org.openqa.selenium.interactions.Actions; import java.util.function.UnaryOperator; public class MouseActions { - private static final String LOG_DELIMITER = "::"; - private final Logger logger = Logger.getInstance(); private IElement element; private String type; private String name; @@ -32,7 +27,7 @@ public MouseActions(IElement element, String type) { public void click() { infoLoc("loc.clicking"); new JsActions(element, type).highlightElement(); - performAction(actions -> actions.click()); + performAction(Actions::click); } /** @@ -48,8 +43,7 @@ public void rightClick() { */ public void moveMouseToElement() { infoLoc("loc.moving"); - element.getElement().getCoordinates().inViewPort(); - performAction(actions -> actions.moveToElement(element.getElement())); + performAction(actions -> actions); } /** @@ -66,31 +60,27 @@ public void moveMouseFromElement() { */ public void doubleClick() { infoLoc("loc.clicking.double"); - ElementActionRetrier.doWithRetry(() -> (getBrowser().getDriver()).getMouse().mouseMove(element.getElement().getCoordinates())); + AqualityServices.get(IElementActionRetrier.class).doWithRetry( + () -> (getBrowser().getDriver()).getMouse().mouseMove(element.getElement().getCoordinates())); performAction(actions -> actions.doubleClick(element.getElement())); } private void performAction(UnaryOperator function) { Actions actions = new Actions(getBrowser().getDriver()).moveToElement(element.getElement()); - ElementActionRetrier.doWithRetry(() -> - function.apply(actions).build().perform()); + AqualityServices.get(IElementActionRetrier.class).doWithRetry(() -> + function.apply(actions).build().perform()); } /** * The implementation of a method for logging of MouseActions * - * @param message Message to display in the log - * @return Formatted message (containing the name and type of item) + * @param key key in localization resource of message to display in the log. */ - private String formatActionMessage(final String message) { - return String.format("%1$s '%2$s' %3$s %4$s", type, name, LOG_DELIMITER, message); - } - private void infoLoc(String key) { - logger.info(formatActionMessage(LocalizationManager.getInstance().getValue(key))); + AqualityServices.getLocalizedLogger().infoElementAction(type, name, key); } - private Browser getBrowser(){ - return BrowserManager.getBrowser(); + private Browser getBrowser() { + return AqualityServices.getBrowser(); } } diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElement.java b/src/main/java/aquality/selenium/elements/interfaces/IElement.java index e34a452..5f61118 100644 --- a/src/main/java/aquality/selenium/elements/interfaces/IElement.java +++ b/src/main/java/aquality/selenium/elements/interfaces/IElement.java @@ -1,51 +1,23 @@ package aquality.selenium.elements.interfaces; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.elements.ElementType; import aquality.selenium.elements.HighlightState; import aquality.selenium.elements.actions.JsActions; import aquality.selenium.elements.actions.MouseActions; import org.openqa.selenium.By; import org.openqa.selenium.Keys; -import org.openqa.selenium.remote.RemoteWebElement; -public interface IElement extends IParent { - - /** - * Get clear WebElement - * - * @return WebElement - */ - RemoteWebElement getElement(); - - /** - * Get clear WebElement - * - * @param timeout Timeout for waiting - * @return WebElement - */ - RemoteWebElement getElement(Long timeout); - - /** - * Get element locator - * - * @return Element locator - */ - By getLocator(); - - /** - * get element name - * @return name - */ - String getName(); +public interface IElement extends aquality.selenium.core.elements.interfaces.IElement { /** * Send keys. + * + * @param key key for sending. */ - void sendKeys(Keys key); - - /** - * Click on the item. - */ - void click(); + default void sendKeys(Keys key) { + sendKeys(key.toString()); + } /** * Click on an item and wait for the page is loaded @@ -57,9 +29,13 @@ public interface IElement extends IParent { * * @return Text of element */ - String getText(); + default String getText() { + return getText(HighlightState.DEFAULT); + } - /** return text of element with highlighting or not before getting text + /** + * return text of element with highlighting or not before getting text + * * @param highlightState if HIGHLIGHT: create red border around element that we interact while getting text * @return text of element */ @@ -71,12 +47,15 @@ public interface IElement extends IParent { * @param attr Attribute name * @return Attribute value */ - String getAttribute(String attr); + default String getAttribute(String attr) { + return getAttribute(attr, HighlightState.DEFAULT); + } /** * returns attribute value of element with highlighting or not before getting text + * * @param highlightState if HIGHLIGHT: create red border around element that we interact while getting text - * @param attr html attribute name + * @param attr html attribute name * @return Attribute value */ String getAttribute(String attr, HighlightState highlightState); @@ -87,12 +66,14 @@ public interface IElement extends IParent { * @param propertyName css value name * @return css value */ - String getCssValue(String propertyName); + default String getCssValue(String propertyName) { + return getCssValue(propertyName, HighlightState.DEFAULT); + } /** * Gets css value of the element. * - * @param propertyName css value name + * @param propertyName css value name * @param highlightState if HIGHLIGHT: create red border around element that we interact while getting css value * @return css value */ @@ -108,23 +89,71 @@ public interface IElement extends IParent { /** * Focuses the element */ - void focus(); + default void focus() { + getJsActions().setFocus(); + } /** * Gets object for class designed to perform javascript actions + * * @return JsActions object */ JsActions getJsActions(); /** * Gets class designed to perform mouse actions + * * @return MouseActions class */ MouseActions getMouseActions(); /** - * Provides ability to define of element's state (whether it is displayed, exists or not) and respective waiting functions - * @return provider to define element's state + * Find an element in the parent element + * + * @param childLoc child element locator + * @param name output name in logs + * @param elementType type of the element to be obtained + * @param state visibility state of target element + * @param type of the element to be obtained + * @return found child element + */ + T findChildElement(By childLoc, String name, ElementType elementType, ElementState state); + + /** + * Find an element in the parent element with default name. + * + * @param childLoc child element locator + * @param elementType type of the element to be obtained + * @param state visibility state of target element + * @param type of the element to be obtained + * @return found child element */ - IElementStateProvider state(); + default T findChildElement(By childLoc, ElementType elementType, ElementState state) { + return findChildElement(childLoc, null, elementType, state); + } + + /** + * Find an element in the parent element with DISPLAYED state and default name. + * + * @param childLoc child element locator + * @param elementType type of the element to be obtained + * @param type of the element to be obtained + * @return found child element + */ + default T findChildElement(By childLoc, ElementType elementType) { + return findChildElement(childLoc, null, elementType, ElementState.DISPLAYED); + } + + /** + * Find an element in the parent element with DISPLAYED state + * + * @param childLoc child element locator + * @param name output name in logs + * @param elementType type of the element to be obtained + * @param type of the element to be obtained + * @return found child element + */ + default T findChildElement(By childLoc, String name, ElementType elementType) { + return findChildElement(childLoc, name, elementType, ElementState.DISPLAYED); + } } diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java b/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java index 5637a43..d7e9537 100644 --- a/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java +++ b/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java @@ -1,8 +1,8 @@ package aquality.selenium.elements.interfaces; -import aquality.selenium.elements.ElementState; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.ElementType; -import aquality.selenium.elements.ElementsCount; import org.openqa.selenium.By; import java.util.List; @@ -10,11 +10,12 @@ /** * Defines the interface used to create the elements. */ -public interface IElementFactory { +public interface IElementFactory extends aquality.selenium.core.elements.interfaces.IElementFactory { /** * Creates element that implements IButton interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements IButton interface */ default IButton getButton(By locator, String name) { @@ -23,17 +24,21 @@ default IButton getButton(By locator, String name) { /** * Creates element that implements IButton interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements IButton interface */ - IButton getButton(By locator, String name, ElementState state); + default IButton getButton(By locator, String name, ElementState state) { + return get(ElementType.BUTTON, locator, name, state); + } /** * Creates element that implements ICheckBox interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements ICheckBox interface */ default ICheckBox getCheckBox(By locator, String name) { @@ -42,17 +47,21 @@ default ICheckBox getCheckBox(By locator, String name) { /** * Creates element that implements ICheckBox interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements ICheckBox interface */ - ICheckBox getCheckBox(By locator, String name, ElementState state); + default ICheckBox getCheckBox(By locator, String name, ElementState state) { + return get(ElementType.CHECKBOX, locator, name, state); + } /** * Creates element that implements IComboBox interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements IComboBox interface */ default IComboBox getComboBox(By locator, String name) { @@ -61,17 +70,21 @@ default IComboBox getComboBox(By locator, String name) { /** * Creates element that implements IComboBox interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements IComboBox interface */ - IComboBox getComboBox(By locator, String name, ElementState state); + default IComboBox getComboBox(By locator, String name, ElementState state) { + return get(ElementType.COMBOBOX, locator, name, state); + } /** * Creates element that implements ILabel interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements ILabel interface */ default ILabel getLabel(By locator, String name) { @@ -80,17 +93,21 @@ default ILabel getLabel(By locator, String name) { /** * Creates element that implements ILabel interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements ILabel interface */ - ILabel getLabel(By locator, String name, ElementState state); + default ILabel getLabel(By locator, String name, ElementState state) { + return get(ElementType.LABEL, locator, name, state); + } /** * Creates element that implements ILink interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements ILink interface */ default ILink getLink(By locator, String name) { @@ -99,17 +116,21 @@ default ILink getLink(By locator, String name) { /** * Creates element that implements ILink interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements ILink interface */ - ILink getLink(By locator, String name, ElementState state); + default ILink getLink(By locator, String name, ElementState state) { + return get(ElementType.LINK, locator, name, state); + } /** * Creates element that implements IRadioButton interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements IRadioButton interface */ default IRadioButton getRadioButton(By locator, String name) { @@ -118,17 +139,21 @@ default IRadioButton getRadioButton(By locator, String name) { /** * Creates element that implements IRadioButton interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements IRadioButton interface */ - IRadioButton getRadioButton(By locator, String name, ElementState state); + default IRadioButton getRadioButton(By locator, String name, ElementState state) { + return get(ElementType.RADIOBUTTON, locator, name, state); + } /** * Creates element that implements ITextBox interface. + * * @param locator Element locator - * @param name Element name + * @param name Element name * @return Instance of element that implements ITextBox interface */ default ITextBox getTextBox(By locator, String name) { @@ -137,149 +162,181 @@ default ITextBox getTextBox(By locator, String name) { /** * Creates element that implements ITextBox interface. + * * @param locator Element locator - * @param name Element name - * @param state Element state + * @param name Element name + * @param state Element state * @return Instance of element that implements ITextBox interface */ - ITextBox getTextBox(By locator, String name, ElementState state); + default ITextBox getTextBox(By locator, String name, ElementState state) { + return get(ElementType.TEXTBOX, locator, name, state); + } /** - * Creates an instance of custom element that implements IElement interface. - * @param supplier Delegate that defines constructor of element - * @param locator Element locator - * @param name Element name - * @param Type of custom element that has to implement IElement - * @return Instance of custom element that implements IElement interface + * Create element according to passed parameters. + * + * @param type Type of the element to be obtained + * @param locator Locator of the target element. + * @param name Name of the target element. + * @param state Visibility state of the target element. + * @param Type of the target element. + * @return Instance of custom element. */ - default T getCustomElement(IElementSupplier supplier, By locator, String name) { - return getCustomElement(supplier, locator, name, ElementState.DISPLAYED); + default T get(ElementType type, By locator, String name, ElementState state) { + return getCustomElement(type.getClazz(), locator, name, state); } /** - * Creates an instance of custom element that implements IElement interface. - * @param supplier Delegate that defines constructor of element - * @param locator Element locator - * @param name Element name - * @param state Element state - * @param Type of custom element that has to implement IElement - * @return Instance of custom element that implements IElement interface + * Create element according to passed parameters. + * + * @param type Type of the element to be obtained + * @param locator Locator of the target element. + * @param name Name of the target element. + * @param Type of the target element. + * @return Instance of custom element. */ - T getCustomElement(IElementSupplier supplier, By locator, String name, ElementState state); + default T get(ElementType type, By locator, String name) { + return get(type, locator, name, ElementState.DISPLAYED); + } /** * Find an element in the parent element * - * @param childLoc Child element locator - * @param clazz class or interface of the element to be obtained + * @param childLoc Child element locator + * @param type Type of the element to be obtained + * @param name Child element name. * @param parentElement parent element for relative search of child element - * @param state visibility state of target element + * @param state visibility state of target elements + * @param Type of the target element. * @return found child element */ - T findChildElement(IElement parentElement, By childLoc, - Class clazz, ElementState state); + default T findChildElement(IElement parentElement, By childLoc, String name, ElementType type, + ElementState state) { + return findChildElement(parentElement, childLoc, name, type.getClazz(), state); + } /** - * Find an element in the parent element + * Finds child element in any state by its locator relative to parent element. * - * @param childLoc Child element locator - * @param supplier required element's supplier - * @param parentElement parent element for relative search of child element - * @param state visibility state of target element - * @return found child element + * @param childLoc Locator of child element relative to its parent. + * @param type Type of the element to be obtained + * @param name Child element name. + * @param parentElement Parent element for relative search of child element. + * @param Type of the target element. + * @return Child element. */ - T findChildElement(IElement parentElement, By childLoc, - IElementSupplier supplier, ElementState state); + default T findChildElement(IElement parentElement, By childLoc, String name, + ElementType type) { + return findChildElement(parentElement, childLoc, name, type, ElementState.EXISTS_IN_ANY_STATE); + } /** - * Find an element in the parent element + * Finds child element by its locator relative to parent element. * - * @param childLoc Child element locator - * @param type the type of the element to be obtained - * @param parentElement parent element for relative search of child element - * @param state visibility state of target elements - * @return found child element - + * @param childLoc Locator of child element relative to its parent. + * @param type Type of the element to be obtained + * @param parentElement Parent element for relative search of child element. + * @param state Visibility state of child element. + * @param Type of the target element. + * @return Child element. */ - T findChildElement(IElement parentElement, By childLoc, ElementType type, - ElementState state); + default T findChildElement(IElement parentElement, By childLoc, + ElementType type, ElementState state) { + return findChildElement(parentElement, childLoc, null, type, state); + } /** - * Find list of elements + * Finds child element existing in any state by its locator relative to parent element. * - * @param locator Elements selector - * @param supplier required elements' supplier - * @param count type of expected count of elements - * @param state visibility state of target elements - * @return list of elements + * @param childLoc Locator of child element relative to its parent. + * @param type Type of the element to be obtained + * @param parentElement Parent element for relative search of child element. + * @param Type of the target element. + * @return Child element. */ - List findElements(By locator, IElementSupplier supplier, ElementsCount count, - ElementState state); + default T findChildElement(IElement parentElement, By childLoc, ElementType type) { + return findChildElement(parentElement, childLoc, null, type, ElementState.EXISTS_IN_ANY_STATE); + } /** * Find list of elements * * @param locator Elements selector - * @param clazz class or interface of the element to be obtained - * @param count type of expected count of elements + * @param name elements' name. + * @param type Type of elements to be obtained + * @param state visibility state of target elements + * @param count type of expected count of elements * @return list of elements */ - List findElements(By locator, Class clazz, ElementState state, ElementsCount count); + default List findElements(By locator, String name, ElementType type, ElementsCount count, + ElementState state) { + return findElements(locator, name, type.getClazz(), count, state); + } /** - * Find list of elements + * Find list of elements. * - * @param locator Elements selector - * @param type the type of elements to be obtained - * @param state visibility state of target elements - * @param count type of expected count of elements - * @return list of elements + * @param locator Elements selector. + * @param type Type of elements to be obtained + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param state Visibility state of target elements. + * @param Type of the target element. + * @return List of elements. */ - List findElements(By locator, ElementType type, ElementState state, ElementsCount count); + default List findElements(By locator, ElementType type, ElementsCount count, + ElementState state) { + return findElements(locator, null, type, count, state); + } /** - * Find list of elements + * Find list of elements. * - * @param locator Elements selector - * @param clazz class or interface of elements to be obtained - * @return list of elements + * @param locator Elements selector. + * @param type Type of elements to be obtained + * @param Type of the target element. + * @return List of elements. */ - default List findElements(By locator, Class clazz) { - return findElements(locator, clazz, ElementState.DISPLAYED, ElementsCount.MORE_THEN_ZERO); + default List findElements(By locator, ElementType type) { + return findElements(locator, type, ElementsCount.ANY, ElementState.DISPLAYED); } /** - * Find list of elements + * Find list of elements. * - * @param locator Elements selector - * @param clazz class or interface of elements to be obtained - * @param count type of expected count of elements - * @return list of elements + * @param locator Elements selector. + * @param type Type of elements to be obtained + * @param name Child element name. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param Type of the target element. + * @return List of elements. */ - default List findElements(By locator, Class clazz, ElementsCount count) { - return findElements(locator, clazz, ElementState.DISPLAYED, count); + default List findElements(By locator, String name, ElementType type, ElementsCount count) { + return findElements(locator, name, type, count, ElementState.DISPLAYED); } /** - * Find list of elements + * Find list of elements. * - * @param locator Elements selector - * @param type the type of elements to be obtained - * @return list of elements + * @param locator Elements selector. + * @param name Child element name. + * @param type Type of elements to be obtained + * @param Type of the target element. + * @return List of elements. */ - default List findElements(By locator, ElementType type) { - return findElements(locator, type, ElementsCount.MORE_THEN_ZERO); + default List findElements(By locator, String name, ElementType type) { + return findElements(locator, name, type, ElementsCount.ANY); } /** - * Find list of elements + * Find list of elements. * - * @param locator Elements selector - * @param type the type of elements to be obtained - * @param count type of expected count of elements - * @return list of elements + * @param locator Elements selector. + * @param type Type of elements to be obtained + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param Type of the target element. + * @return List of elements. */ - default List findElements(By locator, ElementType type, ElementsCount count) { - return findElements(locator, type, ElementState.DISPLAYED, count); + default List findElements(By locator, ElementType type, ElementsCount count) { + return findElements(locator, type, count, ElementState.DISPLAYED); } } diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElementFinder.java b/src/main/java/aquality/selenium/elements/interfaces/IElementFinder.java deleted file mode 100644 index a63050c..0000000 --- a/src/main/java/aquality/selenium/elements/interfaces/IElementFinder.java +++ /dev/null @@ -1,46 +0,0 @@ -package aquality.selenium.elements.interfaces; - -import aquality.selenium.elements.ElementState; -import org.openqa.selenium.By; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebElement; - -import java.util.List; - -/** - * Provides ability to find elements in desired ElementState - */ -public interface IElementFinder extends SearchContext { - - /** - * Finds elements in desired ElementState - * @param locator elements locator - * @param timeout timeout for search - * @param state desired ElementState - * @return list of found elements - */ - List findElements(By locator, long timeout, ElementState state); - - /** - * Finds element in desired ElementState - * @param locator elements locator - * @param timeout timeout for search - * @param state desired ElementState - * @throws org.openqa.selenium.NoSuchElementException if element was not found in time in desired state - * @return found element - */ - WebElement findElement(By locator, long timeout, ElementState state); - - default List findElements(By by) { - return findElements(by, getDefaultTimeout(), ElementState.EXISTS_IN_ANY_STATE); - } - - default WebElement findElement(By by) { - return findElement(by, getDefaultTimeout(), ElementState.EXISTS_IN_ANY_STATE); - } - - /** - * @return default timeout for element waiting - */ - long getDefaultTimeout(); -} diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElementStateProvider.java b/src/main/java/aquality/selenium/elements/interfaces/IElementStateProvider.java deleted file mode 100644 index 7db507f..0000000 --- a/src/main/java/aquality/selenium/elements/interfaces/IElementStateProvider.java +++ /dev/null @@ -1,135 +0,0 @@ -package aquality.selenium.elements.interfaces; - -/** - * Provides ability to define of element's state (whether it is displayed, exist or not) - * Also provides respective positive and negative waiting functions - */ -public interface IElementStateProvider { - - /** - * Is an element clickable on the page. - * @return true if element clickable, false otherwise - */ - boolean isClickable(); - - /** - * Waits for is element clickable on the page. - * @param timeout Timeout for waiting - * @return true if element clickable after waiting, false otherwise - */ - boolean waitForClickable(long timeout); - - /** - * Waits for is element clickable on the page. - * Uses condition timeout from settings file for waiting - * @return true if element clickable after waiting, false otherwise - */ - boolean waitForClickable(); - - /** - * Is an element displayed on the page. - * @return true if element displayed, false otherwise - */ - boolean isDisplayed(); - - /** - * Waits for is element displayed on the page. - * @param timeout Timeout for waiting - * @return true if element displayed after waiting, false otherwise - */ - boolean waitForDisplayed(long timeout); - - /** - * Waits for is element displayed on the page. - * Uses condition timeout from settings file for waiting - * @return true if element displayed after waiting, false otherwise - */ - boolean waitForDisplayed(); - - /** - * Waits for is element displayed on the page. - * @param timeout Timeout for waiting - * @return true if element displayed after waiting, false otherwise - */ - boolean waitForNotDisplayed(long timeout); - - - /** - * Waits for is element displayed on the page. - * Uses condition timeout from settings file for waiting - * @return true if element displayed after waiting, false otherwise - */ - boolean waitForNotDisplayed(); - - /** - * Is an element exist in DOM (without visibility check) - * @return true if element exist, false otherwise - */ - boolean isExist(); - - /** - * Waits until element is exist in DOM (without visibility check). - * @param timeout Timeout for waiting - * @return true if element exist after waiting, false otherwise - */ - boolean waitForExist(long timeout); - - - /** - * Waits until element is exist in DOM (without visibility check). - * Uses condition timeout from settings file for waiting - * @return true if element exist after waiting, false otherwise - */ - boolean waitForExist(); - - /** - * Waits until element does not exist in DOM (without visibility check). - * - * @return true if element does not exist after waiting, false otherwise - */ - boolean waitForNotExist(long timeout); - - /** - * Waits until element does not exist in DOM (without visibility check). - * Uses condition timeout from settings file for waiting - * @return true if element does not exist after waiting, false otherwise - */ - boolean waitForNotExist(); - - /** - * Check that the element is enabled (performed by a class member) - * - * @return true if enabled - */ - boolean isEnabled(); - - /** - * Check that the element is enabled (performed by a class member) - * - * @param timeout Timeout for waiting - * @return true if enabled - */ - boolean waitForEnabled(long timeout); - - - /** - * Check that the element is enabled (performed by a class member) - * Uses condition timeout from settings file for waiting - * @return true if enabled - */ - boolean waitForEnabled(); - - /** - * Waits until element does not enabled in DOM - * - * @return true if element does not enabled after waiting, false otherwise - */ - boolean waitForNotEnabled(long timeout); - - /** - * Waits until element does not enabled in DOM - * Uses condition timeout from settings file for waiting - * @return true if element does not enabled after waiting, false otherwise - */ - boolean waitForNotEnabled(); -} diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElementSupplier.java b/src/main/java/aquality/selenium/elements/interfaces/IElementSupplier.java deleted file mode 100644 index e78110c..0000000 --- a/src/main/java/aquality/selenium/elements/interfaces/IElementSupplier.java +++ /dev/null @@ -1,30 +0,0 @@ -package aquality.selenium.elements.interfaces; - -import aquality.selenium.elements.ElementState; -import org.openqa.selenium.By; - -/** - * Describes interface to supply class which implements IElement interface - * @param type of the element to be supplied - */ -public interface IElementSupplier { - - /** - * Returns an instance of element - * @param locator By locator - * @param name output name in logs - * @param state desired element's state - * @return an instance of element - */ - T get(By locator, String name, ElementState state); - - /** - * Returns an instance of element which desired to be in DISPLAYED {@link ElementState} - * @param locator By locator - * @param name output name in logs - * @return an instance of element - */ - default T get(By locator, String name) { - return get(locator, name, ElementState.DISPLAYED); - } -} diff --git a/src/main/java/aquality/selenium/elements/interfaces/IParent.java b/src/main/java/aquality/selenium/elements/interfaces/IParent.java deleted file mode 100644 index b26735b..0000000 --- a/src/main/java/aquality/selenium/elements/interfaces/IParent.java +++ /dev/null @@ -1,62 +0,0 @@ -package aquality.selenium.elements.interfaces; - -import aquality.selenium.elements.ElementState; -import aquality.selenium.elements.ElementType; -import org.openqa.selenium.By; - -public interface IParent { - - /** - * Find an element in the parent element - * - * @param childLoc Child element locator - * @param type the type of the element to be obtained - - * @return child element - */ - default T findChildElement(By childLoc, ElementType type){ - return findChildElement(childLoc, type, ElementState.DISPLAYED); - } - - /** - * Find an element in the parent element - * - * @param childLoc Child element locator - * @param type the type of the element to be obtained - * @param state visibility state of target element - - * @return child element - */ - T findChildElement(By childLoc, ElementType type, ElementState state); - - /** - * Find an element in the parent element - * - * @param childLoc Child element locator - * @param clazz class or interface of the element to be obtained - * @return found child element - */ - default T findChildElement(By childLoc, Class clazz){ - return findChildElement(childLoc, clazz, ElementState.DISPLAYED); - } - - /** - * Find an element in the parent element - * - * @param childLoc Child element locator - * @param clazz class or interface of the element to be obtained - * @param state visibility state of target element - * @return found child element - */ - T findChildElement(By childLoc, Class clazz, ElementState state); - - /** - * Find an element in the parent element - * - * @param childLoc Child element locator - * @param supplier required element's supplier - * @param state visibility state of target element - * @return found child element - */ - T findChildElement(By childLoc, IElementSupplier supplier, ElementState state); -} diff --git a/src/main/java/aquality/selenium/elements/interfaces/IRadioButton.java b/src/main/java/aquality/selenium/elements/interfaces/IRadioButton.java index f47b5af..7e3ec6e 100644 --- a/src/main/java/aquality/selenium/elements/interfaces/IRadioButton.java +++ b/src/main/java/aquality/selenium/elements/interfaces/IRadioButton.java @@ -1,4 +1,11 @@ package aquality.selenium.elements.interfaces; public interface IRadioButton extends IElement { + + /** + * Gets RadioButton state. + * + * @return True if checked and false otherwise. + */ + boolean isChecked(); } diff --git a/src/main/java/aquality/selenium/elements/interfaces/ITextBox.java b/src/main/java/aquality/selenium/elements/interfaces/ITextBox.java index 833f3f1..77e9dc7 100644 --- a/src/main/java/aquality/selenium/elements/interfaces/ITextBox.java +++ b/src/main/java/aquality/selenium/elements/interfaces/ITextBox.java @@ -44,6 +44,7 @@ public interface ITextBox extends IElement { /** * Focuses on the element using send keys */ + @Override void focus(); /** diff --git a/src/main/java/aquality/selenium/forms/Form.java b/src/main/java/aquality/selenium/forms/Form.java index 59df6c1..970af87 100644 --- a/src/main/java/aquality/selenium/forms/Form.java +++ b/src/main/java/aquality/selenium/forms/Form.java @@ -1,25 +1,22 @@ package aquality.selenium.forms; -import aquality.selenium.elements.ElementFactory; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.localization.ILocalizedLogger; import aquality.selenium.elements.interfaces.IElementFactory; -import aquality.selenium.logger.Logger; +import aquality.selenium.elements.interfaces.ILabel; import org.openqa.selenium.By; import org.openqa.selenium.Dimension; public abstract class Form { - - private static final Logger logger = Logger.getInstance(); /** * Locator for specified form */ - protected final By locator; + private final By locator; /** * Name of specified form */ - protected final String name; - - private final IElementFactory elementFactory; + private final String name; /** * Constructor with parameters @@ -27,44 +24,69 @@ public abstract class Form { protected Form(By locator, String name) { this.locator = locator; this.name = name; - this.elementFactory = new ElementFactory(); } /** - * Return form state for form locator + * Locator for specified form. * - * @return True - form is opened, - * False - form is not opened + * @return locator. */ - public boolean isFormDisplayed() { - return getElementFactory().getLabel(locator, name).state().waitForDisplayed(); + public By getLocator() { + return locator; + } + + /** + * Name of specified form. + * + * @return name. + */ + public String getName() { + return name; } /** * Return form state for form locator * - * @param timeout timeout for action * @return True - form is opened, * False - form is not opened */ - public boolean isFormDisplayed(Long timeout) { - return getElementFactory().getLabel(locator, name).state().waitForDisplayed(timeout); + public boolean isDisplayed() { + return getElementFactory().getLabel(locator, name).state().waitForDisplayed(); } /** * Scroll form without scrolling entire page + * * @param x horizontal coordinate * @param y vertical coordinate */ public void scrollBy(int x, int y) { - getElementFactory().getLabel(locator, name).getJsActions().scrollBy(x, y); + getFormLabel().getJsActions().scrollBy(x, y); + } + + public Dimension getSize() { + return getFormLabel().getElement().getSize(); } - public Dimension getFormSize() { - return getElementFactory().getLabel(locator, name).getElement().getSize(); + private ILabel getFormLabel() { + return getElementFactory().getLabel(locator, name); } - protected IElementFactory getElementFactory(){ - return elementFactory; + /** + * Element factory {@link IElementFactory} + * + * @return instance of ElementFactory. + */ + protected IElementFactory getElementFactory() { + return AqualityServices.getElementFactory(); + } + + /** + * Localized logger {@link ILocalizedLogger} + * + * @return instance of localized logger. + */ + protected ILocalizedLogger getLogger() { + return AqualityServices.getLocalizedLogger(); } } diff --git a/src/main/java/aquality/selenium/localization/LocalizationManager.java b/src/main/java/aquality/selenium/localization/LocalizationManager.java deleted file mode 100644 index 2da0e08..0000000 --- a/src/main/java/aquality/selenium/localization/LocalizationManager.java +++ /dev/null @@ -1,24 +0,0 @@ -package aquality.selenium.localization; - -import aquality.selenium.configuration.Configuration; -import aquality.selenium.utils.JsonFile; - -public class LocalizationManager { - - private final JsonFile localManager; - private static ThreadLocal instance = ThreadLocal.withInitial(LocalizationManager::new); - - private LocalizationManager(){ - SupportedLanguage language = Configuration.getInstance().getLoggerConfiguration().getLanguage(); - String translateDictFile = String.format("localization/%1$s.json", language.name().toLowerCase()); - localManager = new JsonFile(translateDictFile); - } - - public static LocalizationManager getInstance() { - return instance.get(); - } - - public String getValue(final String key) { - return localManager.getValue("/" + key).toString(); - } -} diff --git a/src/main/java/aquality/selenium/localization/SupportedLanguage.java b/src/main/java/aquality/selenium/localization/SupportedLanguage.java deleted file mode 100644 index 49ecd98..0000000 --- a/src/main/java/aquality/selenium/localization/SupportedLanguage.java +++ /dev/null @@ -1,5 +0,0 @@ -package aquality.selenium.localization; - -public enum SupportedLanguage { - EN,RU -} diff --git a/src/main/java/aquality/selenium/logger/Logger.java b/src/main/java/aquality/selenium/logger/Logger.java deleted file mode 100644 index b91f359..0000000 --- a/src/main/java/aquality/selenium/logger/Logger.java +++ /dev/null @@ -1,121 +0,0 @@ -package aquality.selenium.logger; - -import org.apache.log4j.Appender; - -/** - * This class is using for a creating extended log. It implements a Singleton pattern - */ -public final class Logger { - - private static ThreadLocal log4J = ThreadLocal.withInitial(() - -> org.apache.log4j.Logger.getLogger(String.valueOf(Thread.currentThread().getId()))); - private static ThreadLocal instance = ThreadLocal.withInitial(Logger::new); - - private Logger() { - } - - /** - * Gets Logger instance - * - * @return Logger instance - */ - public static Logger getInstance() { - return instance.get(); - } - - /** - * Adds appender - * @param appender Appender to be added - */ - public Logger addAppender(Appender appender){ - log4J.get().addAppender(appender); - return getInstance(); - } - - /** - * Removes appender - * @param appender Appender to be removed - * @return Logger instance - */ - public Logger removeAppender(Appender appender){ - log4J.get().removeAppender(appender); - return getInstance(); - } - - /** - * Debug log - * - * @param message Message - */ - public void debug(String message) { - log4J.get().debug(message); - } - - /** - * Debug log - * - * @param message Message - * @param throwable Throwable - */ - public void debug(String message, Throwable throwable) { - log4J.get().debug(message, throwable); - } - - /** - * Info log - * - * @param message Message - */ - public void info(String message) { - log4J.get().info(message); - } - - /** - * Warning log - * - * @param message Message - */ - public void warn(String message) { - log4J.get().warn(message); - } - - /** - * Error log - * - * @param message Message - */ - public void error(String message) { - log4J.get().error(message); - } - - /** - * Fatal log - * - * @param message Message - * @param throwable Throwable - */ - public void fatal(final String message, Throwable throwable) { - log4J.get().fatal(String.format("%s: %s", message, throwable.toString())); - } - - /** - * tries to get localized value by passed key, then applies String.format to fetched value and params - * then makes record in the log output - * @param key key from localized dictionary - * @param params list of params to format - */ - public void info(String key, Object... params) { - log4J.get().info(String.format(key, params)); - } - - /** - * tries to get localized value by passed key, then applies String.format to fetched value and params - * then makes record in the log output - * @param key key from localized dictionary - * @param params list of params to format - */ - public void debug(String key, Object... params) { - log4J.get().debug(String.format(key, params)); - } -} - diff --git a/src/main/java/aquality/selenium/utils/ElementActionRetrier.java b/src/main/java/aquality/selenium/utils/ElementActionRetrier.java deleted file mode 100644 index b3d7899..0000000 --- a/src/main/java/aquality/selenium/utils/ElementActionRetrier.java +++ /dev/null @@ -1,74 +0,0 @@ -package aquality.selenium.utils; - -import aquality.selenium.configuration.Configuration; -import aquality.selenium.configuration.IRetryConfiguration; -import org.openqa.selenium.InvalidElementStateException; -import org.openqa.selenium.StaleElementReferenceException; - -import java.util.Optional; -import java.util.function.Supplier; - -public class ElementActionRetrier { - - private ElementActionRetrier() { - throw new IllegalStateException("Utility class"); - } - - /** - * Retries the action when "StaleElementReferenceException" occurs. - * @param runnable - */ - public static void doWithRetry(Runnable runnable) - { - Supplier supplier = () -> { - runnable.run(); - return true; - }; - doWithRetry(supplier); - } - - /** - * Retries the function when "StaleElementReferenceException" occures. - * @param function Supplier to be applied - * @param Return type of function - * @return Result of the function - */ - public static T doWithRetry(Supplier function) - { - IRetryConfiguration retryConfiguration = Configuration.getInstance().getRetryConfiguration(); - int retryAttemptsLeft = retryConfiguration.getNumber(); - long actualInterval = retryConfiguration.getPollingInterval(); - Optional result = Optional.empty(); - while(retryAttemptsLeft >= 0) - { - try - { - result = Optional.of(function.get()); - break; - } - catch (Exception exception) - { - if (isExceptionHandled(exception) && retryAttemptsLeft != 0) - { - try { - Thread.sleep(actualInterval); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - retryAttemptsLeft--; - } - else - { - throw exception; - } - } - } - return result.orElse(null); - } - - private static boolean isExceptionHandled(Exception exception) - { - return (exception instanceof StaleElementReferenceException) || - (exception instanceof InvalidElementStateException); - } -} \ No newline at end of file diff --git a/src/main/java/aquality/selenium/utils/JsonFile.java b/src/main/java/aquality/selenium/utils/JsonFile.java deleted file mode 100644 index 09dbeb3..0000000 --- a/src/main/java/aquality/selenium/utils/JsonFile.java +++ /dev/null @@ -1,131 +0,0 @@ -package aquality.selenium.utils; - -import aquality.selenium.logger.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.*; - -/** - * Provides methods to get info from JSON files. - * Note that the value can be overriden via Environment variable with the same name - * (e.g. for json path ".timeouts.timeoutScript" you can set environment variable "timeouts.timeoutScript") - */ -public class JsonFile { - - private final ObjectMapper mapper = new ObjectMapper(); - private final String fileCanonicalPath; - private final String content; - - /** - * Inistantiates class using desired JSON file. - * @param file JSON file. - * @throws IOException if file is not found - */ - public JsonFile(File file) throws IOException { - this.content = getFileContent(file.getCanonicalPath()); - fileCanonicalPath = file.getCanonicalPath(); - } - - /** - * Inistantiates class using desired JSON file. - * @param resourceName path to JSON relatively resources - */ - public JsonFile(String resourceName) { - ResourceFile resourceFile = new ResourceFile(resourceName); - this.content = resourceFile.getFileContent(); - this.fileCanonicalPath = resourceFile.getFileCanonicalPath(); - } - - /** - * Gets value from JSON. - * Note that the value can be overriden via Environment variable with the same name - * (e.g. for json path ".timeouts.timeoutScript" you can set environment variable "timeouts.timeoutScript") - * @param jsonPath Relative jsonPath to the value. - * @return Value from JSON/Environment by jsonPath. - */ - public Object getValue(String jsonPath){ - return getEnvValueOrDefault(jsonPath); - } - - private Object getEnvValueOrDefault(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)); - } - JsonNode node = getJsonNode(jsonPath); - if(node.isBoolean()){ - return envVar == null ? node.asBoolean() : Boolean.parseBoolean(envVar); - }else if(node.isLong()){ - return envVar == null ? node.asLong() : Long.parseLong(envVar); - }else if(node.isInt()){ - return envVar == null ? node.asInt() : Integer.parseInt(envVar); - }else{ - return envVar == null ? node.asText() : envVar; - } - } - - /** - * Gets list of values from JSON. - * @param jsonPath Relative JsonPath to the values. - * @return Values from JSON/Environment by jsonPath. - */ - public List getList(String jsonPath){ - List list = new ArrayList<>(); - getJsonNode(jsonPath).elements().forEachRemaining(node -> list.add(node.asText())); - return list; - } - - /** - * Gets map of values from JSON. - * Note that the value can be overriden via Environment variable with the same name - * (e.g. for json path ".timeouts.timeoutScript" you can set environment variable "timeouts.timeoutScript") - * @param jsonPath - * @return - */ - 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); - } - } - - /** - * Gets content of JsonFile - * @return content of the file - */ - public String getContent() { - return content; - } - - /** - * Gets canonical path to the file - * @return canonical path to the file - */ - public String getFileCanonicalPath() { - return fileCanonicalPath; - } -} diff --git a/src/main/java/aquality/selenium/utils/ResourceFile.java b/src/main/java/aquality/selenium/utils/ResourceFile.java deleted file mode 100644 index 16df99c..0000000 --- a/src/main/java/aquality/selenium/utils/ResourceFile.java +++ /dev/null @@ -1,52 +0,0 @@ -package aquality.selenium.utils; - -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(JsonFile.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 = JsonFile.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; - } - - public String getFileCanonicalPath() { - return fileCanonicalPath; - } - - public String getFileContent() { - return fileContent; - } -} diff --git a/src/main/java/aquality/selenium/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/waitings/ConditionalWait.java deleted file mode 100644 index 6d7fe64..0000000 --- a/src/main/java/aquality/selenium/waitings/ConditionalWait.java +++ /dev/null @@ -1,179 +0,0 @@ -package aquality.selenium.waitings; - -import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.configuration.ITimeoutConfiguration; -import aquality.selenium.localization.LocalizationManager; -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.TimeoutException; -import java.util.function.BooleanSupplier; -import java.util.function.Function; - -public final class ConditionalWait { - - private ConditionalWait() { - throw new IllegalStateException("All methods are static in this 'ConditionalWait' class, class instance is not required"); - } - - /** - * 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 - */ - public static void waitForTrue(BooleanSupplier condition, String message) throws TimeoutException { - waitForTrue(condition, getTimeoutConfiguration().getCondition(), getTimeoutConfiguration().getPollingInterval(), 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 - */ - public static void waitForTrue(BooleanSupplier condition, long timeoutInSeconds, long pollingIntervalInMilliseconds, String message) throws TimeoutException { - if (condition == null) - { - throw new IllegalArgumentException(getLocalizationManager().getValue("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(getLocalizationManager().getValue("loc.wait.timeout.condition"), timeoutInSeconds, message); - throw new TimeoutException(exceptionMessage); - } - - try { - Thread.sleep(pollingIntervalInMilliseconds); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - - /** - * Waits for function will be true or return false. Method does not use WebDriverWait. - * Default timeout condition from settings is using. - * @param condition condition with boolean result (predicate). - * @param message Part of error message in case of Timeout exception. - * @return true if condition is satisfied, false otherwise. - */ - public static boolean waitFor(BooleanSupplier condition, String message) { - return waitFor(condition, - getTimeoutConfiguration().getCondition(), - getTimeoutConfiguration().getPollingInterval(), - message); - } - - /** - * Waits for function will be true or return false. 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 condition is satisfied, false otherwise. - */ - public static boolean waitFor(BooleanSupplier condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message) { - try { - waitForTrue(condition, timeOutInSeconds, pollingIntervalInMilliseconds, message); - return true; - }catch (TimeoutException e){ - return false; - } - } - - /** - * 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 - */ - public static T waitFor(ExpectedCondition condition, String message) { - return waitFor(condition, - getTimeoutConfiguration().getCondition(), - getTimeoutConfiguration().getPollingInterval(), - message, - Collections.singleton(StaleElementReferenceException.class)); - } - - /** - * 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 occurred - */ - public static T waitFor(ExpectedCondition condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message) { - return waitFor(condition, - timeOutInSeconds, - pollingIntervalInMilliseconds, - message, - Collections.singleton(StaleElementReferenceException.class)); - } - - /** - * 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 occurred - */ - public static T waitFor(ExpectedCondition condition, long timeOutInSeconds, long pollingIntervalInMilliseconds, String message, Collection> exceptionsToIgnore) { - getBrowser().setImplicitWaitTimeout(0L); - WebDriverWait wait = new WebDriverWait(getBrowser().getDriver(), timeOutInSeconds); - wait.pollingEvery(Duration.ofMillis(pollingIntervalInMilliseconds)); - wait.withMessage(message); - wait.ignoreAll(exceptionsToIgnore); - - try { - return wait.until(condition); - } finally { - getBrowser().setImplicitWaitTimeout(getTimeoutConfiguration().getImplicit()); - } - } - - private static Browser getBrowser(){ - return BrowserManager.getBrowser(); - } - - private static ITimeoutConfiguration getTimeoutConfiguration(){ - return Configuration.getInstance().getTimeoutConfiguration(); - } - - private static LocalizationManager getLocalizationManager(){ - return LocalizationManager.getInstance(); - } - - private static double getCurrentTime(){ - return System.nanoTime()/Math.pow(10,9); - } -} diff --git a/src/main/resources/localization/en.json b/src/main/resources/localization/en.json index 99c4eb1..cfcfa5c 100644 --- a/src/main/resources/localization/en.json +++ b/src/main/resources/localization/en.json @@ -18,8 +18,6 @@ "loc.browser.implicit.timeout" : "Set implicit timeout '%1$s' in seconds", "loc.browser.script.timeout" : "Set async javascript execution timeout '%1$s' in seconds", "loc.browser.alert.fail" : "Failed while handling alert", - "loc.browser.page.is.not.loaded" : "Page was not loaded during %1$s seconds", - "loc.element.wasnotfoundinstate" : "Element '%1$s' was not found in state %2$s during %3$s seconds", "loc.button" : "Button", "loc.checkbox" : "CheckBox", "loc.checkbox.get.state" : "Getting state", @@ -29,8 +27,11 @@ "loc.clicking.right" : "Clicking right", "loc.combobox" : "ComboBox", "loc.combobox.select.by.text" : "Selecting value by text '%s'", + "loc.combobox.select.by.text.js": "Selecting value by text '{0}' via JavaScript", "loc.combobox.get.texts": "Getting option texts array", + "loc.combobox.get.texts.js": "Getting option texts array via JavaScript", "loc.combobox.get.values" : "Getting values array", + "loc.combobox.get.text.js": "Getting selected text via JavaScript", "loc.combobox.impossible.to.select.contain.value.or.text" : "It is impossible to select option that contains value/text '%1$s' from combobox '%2$s'", "loc.el.getattr" : "Getting attribute '%1$s'", "loc.el.cssvalue" : "Getting css value '%1$s'", @@ -40,6 +41,7 @@ "loc.get.text.js" : "Getting text from element via Javascript", "loc.hover.js" : "Hover mouse over element via JavaScript", "loc.is.present.js" : "Is present via JavaScript", + "loc.get.xpath.js": "Getting XPath locator of element via JavaScript", "loc.label" : "Label", "loc.link" : "Link", "loc.moving" : "Moving mouse to element", @@ -49,20 +51,22 @@ "loc.scrolling.js" : "Scrolling via JavaScript", "loc.selecting.value" : "Selecting value", "loc.send.text" : "Setting text - '%s'", - "loc.setting.value" : "Setting value", + "loc.setting.value" : "Setting value '%s'", "loc.text.clearing" : "Clearing", "loc.text.field" : "Text Field", "loc.text.sending.keys" : "Sending keys '%s'", "loc.text.typing" : "Typing '%s'", "loc.text.masked_value" : "********", - "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'", - "loc.waitexists" : "Wait until element exists in DOM", + "loc.waitexists" : "Wait until element exists in DOM using \"locator\": %1$s", "loc.waitinstate" : "Wait until is present in state %1$s using \"locator\": %2$s", - "loc.waitinvisible" : "Wait until element is not visible", - "loc.waitnotexists" : "Wait until element does not exist in DOM during %1$s seconds", - "loc.no.elements.found.in.state" : "no elements with locator '%1$s' found in state '%2$s' during %3$s seconds", + "loc.waitinvisible" : "Wait until element is not visible using \"locator\": %1$s", + "loc.waitnotexists" : "Wait until element does not exist in DOM using \"locator\": %1$s", + "loc.no.elements.found.in.state" : "No elements with locator '%1$s' found in state '%2$s'", "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'" + "loc.elements.found.but.should.not": "No elements should be found by locator '%1$s'", + "loc.search.of.elements.failed": "Search of element by locator '%1$s' failed", + "loc.element.not.in.state": "Element %1$s has not become %2$s after timeout %3$s", + "loc.get.page.source.failed": "An exception occurred while tried to save the page source" } \ No newline at end of file diff --git a/src/main/resources/localization/ru.json b/src/main/resources/localization/ru.json index 20f07e9..d9c2859 100644 --- a/src/main/resources/localization/ru.json +++ b/src/main/resources/localization/ru.json @@ -18,8 +18,6 @@ "loc.browser.implicit.timeout" : "Установка implicit(неявного) таймаута: '%1$s' секунд", "loc.browser.script.timeout" : "Установка таймаута на выполнение асинхронных javascript вызовов: '%1$s' секунд", "loc.browser.alert.fail" : "Не удалось обработать всплывающее окно", - "loc.browser.page.is.not.loaded" : "Страница не загрузилась в течении %1$s секунд(ы)", - "loc.element.wasnotfoundinstate" : "Элемент '%1$s' в состоянии %2$s не найден в течении %3$s секунд", "loc.button" : "Кнопка", "loc.checkbox" : "Чекбокс", "loc.checkbox.get.state" : "Получение состояния", @@ -29,8 +27,11 @@ "loc.clicking.right" : "Клик правой кнопкой", "loc.combobox" : "Комбобокс", "loc.combobox.select.by.text" : "Выбор значения с текстом '%s'", + "loc.combobox.select.by.text.js": "Выбор значения с текстом '{0}' посредством JavaScript", "loc.combobox.get.texts": "Получение списка текстов опций", + "loc.combobox.get.texts.js": "Получение списка текстов опций посредством JavaScript", "loc.combobox.get.values" : "Получение списка значений", + "loc.combobox.get.text.js": "Получение списка значений посредством JavaScript", "loc.combobox.impossible.to.select.contain.value.or.text" : "Не удаётся выбрать значение которое содержит значение/текст '%1$s' в выпадающем списке '%2$s'", "loc.el.getattr" : "Получение аттрибута '%1$s'", "loc.el.cssvalue" : "Получение значения css '%1$s'", @@ -40,6 +41,7 @@ "loc.get.text.js" : "Получение текста элемента (при помощи JavaScript)", "loc.hover.js" : "Наведение курсора на элемент (при помощи JavaScript)", "loc.is.present.js" : "Присутствует (с помощью JavaScript)", + "loc.get.xpath.js": "Получение XPath локатора элемента (при помощи JavaScript)", "loc.label" : "Надпись", "loc.link" : "Ссылка", "loc.moving" : "Наведение курсора на элемент", @@ -49,20 +51,22 @@ "loc.scrolling.js" : "Скроллинг с помощью JavaScript", "loc.selecting.value" : "Выбор значения", "loc.send.text" : "Ввод текста - '%s'", - "loc.setting.value" : "Установка значения", + "loc.setting.value" : "Установка значения '%s'", "loc.text.clearing" : "Очистка", "loc.text.field" : "Текстовое поле", "loc.text.sending.keys" : "Нажатие клавиши '%s'", "loc.text.typing" : "Ввод текста '%s'", "loc.text.masked_value" : "********", - "loc.wait.condition.cant.be.null": "Ожидаемое условие не должно быть null", "loc.wait.timeout.condition": "Не удалось дождаться ожидаемого условия '%2$s' в течении %1$s секунд(ы)", - "loc.waitexists" : "Ожидаем появления элемента в DOM", + "loc.waitexists" : "Ожидаем появления элемента в DOM используя локатор: %1$s", "loc.waitinstate" : "Ожидание присутствия элемента в состоянии %1$s используя локатор: %2$s", - "loc.waitinvisible" : "Ожидаем пока элемент исчезнет", - "loc.waitnotexists" : "Ожидаем исчезновения элемента из DOM в течении %1$s", - "loc.no.elements.found.in.state" : "не удалось найти элементов по локатору '%1$s' в состоянии '%2$s' на протяжении %3$s секунд", + "loc.waitinvisible" : "Ожидаем пока элемент исчезнет используя локатор: %1$s", + "loc.waitnotexists" : "Ожидаем исчезновения элемента из DOM используя локатор: %1$s", + "loc.no.elements.found.in.state" : "Не удалось найти элементов по локатору '%1$s' в состоянии '%2$s'", "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'" + "loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s'", + "loc.search.of.elements.failed": "Поиск элемента по локатору '%1$s' прошел неудачно", + "loc.element.not.in.state": "Элемент %1$s не стал %2$s после таймаута %3$s", + "loc.get.page.source.failed": "Произошла ошибка во время получения разметки страницы" } \ No newline at end of file diff --git a/src/main/resources/settings.json b/src/main/resources/settings.json index 89302d9..3474692 100644 --- a/src/main/resources/settings.json +++ b/src/main/resources/settings.json @@ -67,5 +67,8 @@ }, "logger": { "language": "en" + }, + "elementCache": { + "isEnabled": false } } diff --git a/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java b/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java index 8168381..9dc73bd 100644 --- a/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java +++ b/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java @@ -1,57 +1,54 @@ package aquality.selenium.localization; -import aquality.selenium.utils.JsonFile; -import org.testng.annotations.*; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.localization.LocalizationManager; +import aquality.selenium.core.logging.Logger; +import aquality.selenium.core.utilities.ISettingsFile; +import aquality.selenium.core.utilities.JsonSettingsFile; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; -import java.io.IOException; import java.lang.reflect.Field; -import static org.testng.Assert.*; +import static org.testng.Assert.assertEquals; public class LocalizationManagerTests { - private static final String fieldLocalManagerName = "localManager"; + private static final String fieldLocalManagerName = "localizationFile"; private static final String tmpDicFilePath = "localization/%1$s.json"; private static final String key = "loc.clicking"; - private static final String languageKey = "logger.language"; - - - @BeforeGroups("unsupportedLanguage") - private void renameLocalizationFolder() { - System.setProperty(languageKey, "UnsupportedLanguage"); - } @DataProvider private Object[][] languagesAndValues() { return new Object[][]{ - {SupportedLanguage.RU, "Клик"}, - {SupportedLanguage.EN, "Clicking"} + {"ru", "Клик"}, + {"en", "Clicking"} }; } @Test public void testGetInstanceShouldReturnSameObjectEachTime() { - assertEquals(LocalizationManager.getInstance(), LocalizationManager.getInstance()); + assertEquals(AqualityServices.get(ILocalizationManager.class), AqualityServices.get(ILocalizationManager.class)); } @Test(dataProvider = "languagesAndValues") - public void testGetValueShouldReturnValueFromSelectedLanguage(SupportedLanguage language, String value) throws NoSuchFieldException, IllegalAccessException, IOException { + public void testGetValueShouldReturnValueFromSelectedLanguage(String language, String value) throws NoSuchFieldException, IllegalAccessException { Field fieldLocalManager = LocalizationManager.class.getDeclaredField(fieldLocalManagerName); fieldLocalManager.setAccessible(true); - JsonFile jsonFileRu = new JsonFile(String.format(tmpDicFilePath, language.name().toLowerCase())); - fieldLocalManager.set(LocalizationManager.getInstance(), jsonFileRu); - assertEquals(LocalizationManager.getInstance().getValue(key), value); + ISettingsFile jsonFile = new JsonSettingsFile(String.format(tmpDicFilePath, language)); + fieldLocalManager.set(AqualityServices.get(ILocalizationManager.class), jsonFile); + assertEquals(AqualityServices.get(ILocalizationManager.class).getLocalizedMessage(key), value); } - @Test(groups = "unsupportedLanguage", priority = -1, expectedExceptions = { IllegalArgumentException.class} ) + @Test public void testShouldGetExceptionIfLocalizationFileIsNotExists() { - LocalizationManager.getInstance(); + Assert.assertThrows(IllegalArgumentException.class, () -> getLocalizationManager("invalid").getLocalizedMessage(key)); } - @AfterGroups("unsupportedLanguage") - private void renameLocalizationFolderToInitial() { - System.clearProperty(languageKey); + private LocalizationManager getLocalizationManager(String language) { + return new LocalizationManager(() -> language, Logger.getInstance()); } - } \ No newline at end of file diff --git a/src/test/java/aquality/selenium/logger/LoggerTests.java b/src/test/java/aquality/selenium/logger/LoggerTests.java index 96a2f48..6825315 100644 --- a/src/test/java/aquality/selenium/logger/LoggerTests.java +++ b/src/test/java/aquality/selenium/logger/LoggerTests.java @@ -1,7 +1,11 @@ package aquality.selenium.logger; +import aquality.selenium.core.logging.Logger; import org.apache.log4j.*; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import java.io.File; import java.io.IOException; diff --git a/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java b/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java index 6c15b91..f897410 100644 --- a/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java +++ b/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java @@ -1,7 +1,8 @@ package aquality.selenium.utils; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.logger.Logger; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.logging.Logger; +import aquality.selenium.core.utilities.IElementActionRetrier; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.InvalidElementStateException; import org.openqa.selenium.StaleElementReferenceException; @@ -9,9 +10,8 @@ import org.testng.annotations.Test; import utils.DurationSample; import utils.Timer; +import utils.Timer.TimeUnit; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.Date; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -21,8 +21,8 @@ public class ElementActionRetrierTests { - private static final int retriesCount = Configuration.getInstance().getRetryConfiguration().getNumber(); - private static final long pollingInterval = Configuration.getInstance().getRetryConfiguration().getPollingInterval(); + private static final int retriesCount = AqualityServices.getConfiguration().getRetryConfiguration().getNumber(); + private static final long pollingInterval = AqualityServices.getConfiguration().getRetryConfiguration().getPollingInterval().toMillis(); @DataProvider @@ -36,16 +36,16 @@ private Object[][] handledExceptions() { @Test public void testRetrierShouldWorkOnceIfMethodSucceeded() { Date startTime = new Date(); - ElementActionRetrier.doWithRetry(() -> true); + getElementActionRetrier().doWithRetry(() -> true); assertTrue(new Date().getTime() - startTime.getTime() < pollingInterval); } @Test(dataProvider = "handledExceptions") public void testRetrierShouldWaitPollingTimeBetweenMethodsCall(RuntimeException handledException) { - Timer timer = new Timer(Timer.TimeUnit.MILLISECONDS); + Timer timer = new Timer(TimeUnit.MILLISECONDS); timer.start(); AtomicBoolean isThrowException = new AtomicBoolean(true); - ElementActionRetrier.doWithRetry(() -> { + getElementActionRetrier().doWithRetry(() -> { if (isThrowException.get()) { isThrowException.set(false); throw handledException; @@ -58,7 +58,7 @@ public void testRetrierShouldWaitPollingTimeBetweenMethodsCall(RuntimeException @Test(expectedExceptions = InvalidArgumentException.class) public void testRetrierShouldThrowUnhandledException() { - ElementActionRetrier.doWithRetry(() -> { + getElementActionRetrier().doWithRetry(() -> { throw new InvalidArgumentException(""); }); } @@ -67,7 +67,7 @@ public void testRetrierShouldThrowUnhandledException() { public void testRetrierShouldWorkCorrectTimes(RuntimeException handledException) { AtomicInteger actualAttempts = new AtomicInteger(0); try { - ElementActionRetrier.doWithRetry(() -> { + getElementActionRetrier().doWithRetry(() -> { Logger.getInstance().info("current attempt is " + actualAttempts.incrementAndGet()); throw handledException; }); @@ -77,28 +77,16 @@ public void testRetrierShouldWorkCorrectTimes(RuntimeException handledException) assertEquals(actualAttempts.get(), retriesCount + 1, "actual attempts count is not match to expected"); } - @Test(expectedExceptions = IllegalAccessException.class) - public void testShouldNotBePossibleInstantiateRetrier() throws IllegalAccessException, InstantiationException { - ElementActionRetrier.class.newInstance(); - } - - @Test(expectedExceptions = InvocationTargetException.class) - public void testShouldNotBePossibleInstantiateRetrierEvenIfUsingReflection() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { - Constructor constructor = ElementActionRetrier.class.getDeclaredConstructor(); - constructor.setAccessible(true); - constructor.newInstance(); - } - @Test public void testRetrierShouldReturnValue() { Object obj = new Object(); - assertEquals(ElementActionRetrier.doWithRetry(() -> obj), obj); + assertEquals(getElementActionRetrier().doWithRetry(() -> obj), obj); } @Test(dataProvider = "handledExceptions", timeOut = 10000) public void testRetrierShouldNotThrowExceptionOnInterruption(RuntimeException handledException) throws InterruptedException { AtomicBoolean isRetrierPaused = new AtomicBoolean(false); - Thread thread = new Thread(() -> ElementActionRetrier.doWithRetry(() -> { + Thread thread = new Thread(() -> getElementActionRetrier().doWithRetry(() -> { isRetrierPaused.set(true); throw handledException; })); @@ -110,4 +98,8 @@ public void testRetrierShouldNotThrowExceptionOnInterruption(RuntimeException ha thread.interrupt(); } + private IElementActionRetrier getElementActionRetrier() { + return AqualityServices.get(IElementActionRetrier.class); + } + } \ No newline at end of file diff --git a/src/test/java/aquality/selenium/waitings/ConditionalWaitTests.java b/src/test/java/aquality/selenium/waitings/ConditionalWaitTests.java index 1599de4..ce3d0ee 100644 --- a/src/test/java/aquality/selenium/waitings/ConditionalWaitTests.java +++ b/src/test/java/aquality/selenium/waitings/ConditionalWaitTests.java @@ -1,29 +1,36 @@ package aquality.selenium.waitings; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.configuration.Configuration; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.configuration.ITimeoutConfiguration; +import aquality.selenium.core.waitings.IConditionalWait; import org.openqa.selenium.StaleElementReferenceException; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; import utils.DurationSample; import utils.Timer; + +import java.time.Duration; 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 static final Duration waitForTimeoutCondition = Duration.ofSeconds(10); + private static final Duration waitForTimeoutPolling = Duration.ofMillis(150); private static final double defaultDeviation = 7; + private IConditionalWait getConditionalWait(){ + return AqualityServices.getConditionalWait(); + } + @Test public void testTimeoutExceptionShouldBeThrownIfConditionIsNotMetAndDefaultTimeoutIsOver() { Timer timer = new Timer(); - Assert.expectThrows(TimeoutException.class, () -> ConditionalWait.waitForTrue(() -> + Assert.expectThrows(TimeoutException.class, () -> getConditionalWait().waitForTrue(() -> { timer.start(); return false; @@ -35,7 +42,7 @@ public void testTimeoutExceptionShouldBeThrownIfConditionIsNotMetAndDefaultTimeo @Test public void testTimeoutExceptionShouldBeThrownIfConditionIsNotMetAndTimeoutIsOver() { Timer timer = new Timer(); - Assert.expectThrows(TimeoutException.class, () -> ConditionalWait.waitForTrue(() -> + Assert.expectThrows(TimeoutException.class, () -> getConditionalWait().waitForTrue(() -> { timer.start(); return false; @@ -47,37 +54,37 @@ public void testTimeoutExceptionShouldBeThrownIfConditionIsNotMetAndTimeoutIsOve @Test public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndTimeoutIsNotOver() throws TimeoutException { Timer timer = new Timer(); - ConditionalWait.waitForTrue(() -> + getConditionalWait().waitForTrue(() -> { timer.start(); return true; }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); DurationSample durationSample = new DurationSample(timer.duration(), waitForTimeoutCondition); - assertTrue(durationSample.getDuration() < waitForTimeoutCondition); + assertTrue(durationSample.getDuration() < waitForTimeoutCondition.getSeconds()); } @Test public void testTimeoutExceptionShouldNotBeThrownIfConditionMetAndDefaultTimeoutIsNotOver() throws TimeoutException { Timer timer = new Timer(); - ConditionalWait.waitForTrue(() -> + getConditionalWait().waitForTrue(() -> { timer.start(); return true; }, "Timeout exception should not be thrown"); DurationSample durationSample = new DurationSample(timer.duration(), getTimeoutConfig().getCondition()); - assertTrue(durationSample.getDuration() < getTimeoutConfig().getCondition()); + assertTrue(durationSample.getDuration() < getTimeoutConfig().getCondition().getSeconds()); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullCannotBePassedAsCondition() throws TimeoutException { - ConditionalWait.waitForTrue(null, "Condition should not be null"); + getConditionalWait().waitForTrue(null, "Condition should not be null"); } @Test public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaultTimeoutIsOver() { Timer timer = new Timer(); try { - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); return false; @@ -94,7 +101,7 @@ public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndDefaul public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeoutIsOver() { Timer timer = new Timer(); try { - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); return false; @@ -111,7 +118,7 @@ public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeou public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeoutIsOverWithIgnoredExceptions() { Timer timer = new Timer(); try { - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); return false; @@ -128,41 +135,41 @@ public void testTimeoutExceptionShouldBeThrownIfDriverConditionIsNotMetAndTimeou public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndDefaultTimeoutIsNotOver() { Timer timer = new Timer(); - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); return true; }, "Conditional should be true"); DurationSample durationSample = new DurationSample(timer.duration(), getTimeoutConfig().getCondition()); - assertTrue(durationSample.getDuration() < getTimeoutConfig().getCondition()); + assertTrue(durationSample.getDuration() < getTimeoutConfig().getCondition().getSeconds()); } @Test public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOverWithIgnoredExceptions() { Timer timer = new Timer(); - boolean conditionResult = ConditionalWait.waitFor((driver) -> + boolean conditionResult = getConditionalWait().waitFor((driver) -> { timer.start(); return true; }, waitForTimeoutCondition, waitForTimeoutPolling, "Conditional should be true"); DurationSample durationSample = new DurationSample(timer.duration(), waitForTimeoutCondition); - assertTrue(durationSample.getDuration() < waitForTimeoutCondition); + assertTrue(durationSample.getDuration() < waitForTimeoutCondition.getSeconds()); assertTrue(conditionResult, "Condition result should be true"); } @Test public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeoutIsNotOver() { Timer timer = new Timer(); - boolean conditionResult = ConditionalWait.waitFor((driver) -> + boolean conditionResult = getConditionalWait().waitFor((driver) -> { timer.start(); return true; }, waitForTimeoutCondition, waitForTimeoutPolling, "Conditional should be true", Collections.singleton(IllegalArgumentException.class)); DurationSample durationSample = new DurationSample(timer.duration(), waitForTimeoutCondition); - assertTrue(durationSample.getDuration() < waitForTimeoutCondition); + assertTrue(durationSample.getDuration() < waitForTimeoutCondition.getSeconds()); assertTrue(conditionResult, "Condition result should be true"); } @@ -170,7 +177,7 @@ public void testTimeoutExceptionShouldNotBeThrownIfDriverConditionIsMetAndTimeou public void testExceptionShouldBeCaughtConditionIsMetAndTimeoutIsNotOver() { Timer timer = new Timer(); try { - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); throw new IllegalArgumentException("I am exception"); @@ -186,7 +193,7 @@ public void testExceptionShouldBeCaughtConditionIsMetAndTimeoutIsNotOver() { public void testStaleElementReferenceExceptionShouldBeCaughtConditionIsMetAndTimeoutIsNotOver() { Timer timer = new Timer(); try { - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); throw new StaleElementReferenceException("I am StaleElementReferenceException"); @@ -202,7 +209,7 @@ public void testStaleElementReferenceExceptionShouldBeCaughtConditionIsMetAndTim public void testStaleElementReferenceExceptionShouldBeCaughtConditionIsMetAndDefaultTimeoutIsNotOver() { Timer timer = new Timer(); try { - ConditionalWait.waitFor((driver) -> + getConditionalWait().waitFor((driver) -> { timer.start(); throw new StaleElementReferenceException("I am StaleElementReferenceException"); @@ -216,20 +223,20 @@ public void testStaleElementReferenceExceptionShouldBeCaughtConditionIsMetAndDef @Test public void testTrueShouldBeReturnedIfConditionIsMetAndTimeoutIsNotOver() { Timer timer = new Timer(); - boolean conditionResult = ConditionalWait.waitFor(() -> + boolean conditionResult = getConditionalWait().waitFor(() -> { timer.start(); return true; }, waitForTimeoutCondition, waitForTimeoutPolling, "Timeout exception should not be thrown"); DurationSample durationSample = new DurationSample(timer.duration(), waitForTimeoutCondition); - assertTrue(durationSample.getDuration() < waitForTimeoutCondition); + assertTrue(durationSample.getDuration() < waitForTimeoutCondition.getSeconds()); assertTrue(conditionResult, "Condition result should be true"); } @Test public void testFalseShouldBeReturnedIfConditionIsNotMetAndTimeoutIsOver() { Timer timer = new Timer(); - boolean conditionResult = ConditionalWait.waitFor(() -> + boolean conditionResult = getConditionalWait().waitFor(() -> { timer.start(); return false; @@ -242,20 +249,20 @@ public void testFalseShouldBeReturnedIfConditionIsNotMetAndTimeoutIsOver() { @Test public void testTrueShouldBeReturnedIfConditionIsMetAndDefaultTimeoutIsNotOver() { Timer timer = new Timer(); - boolean conditionResult = ConditionalWait.waitFor(() -> + boolean conditionResult = getConditionalWait().waitFor(() -> { timer.start(); return true; }, "Timeout exception should not be thrown"); DurationSample durationSample = new DurationSample(timer.duration(), getTimeoutConfig().getCondition()); - assertTrue(durationSample.getDuration() < getTimeoutConfig().getCondition()); + assertTrue(durationSample.getDuration() < getTimeoutConfig().getCondition().getSeconds()); assertTrue(conditionResult, "Condition result should be true"); } @Test public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver() { Timer timer = new Timer(); - boolean conditionResult = ConditionalWait.waitFor(() -> + boolean conditionResult = getConditionalWait().waitFor(() -> { timer.start(); return false; @@ -267,10 +274,10 @@ public void testFalseShouldBeReturnedIfConditionIsNotMetAndDefaultTimeoutIsOver( @AfterMethod public void after() { - BrowserManager.getBrowser().quit(); + AqualityServices.getBrowser().quit(); } private ITimeoutConfiguration getTimeoutConfig() { - return Configuration.getInstance().getTimeoutConfiguration(); + return AqualityServices.getConfiguration().getTimeoutConfiguration(); } } diff --git a/src/test/java/automationpractice/forms/ProductListForm.java b/src/test/java/automationpractice/forms/ProductListForm.java index 42ef047..7d3885c 100644 --- a/src/test/java/automationpractice/forms/ProductListForm.java +++ b/src/test/java/automationpractice/forms/ProductListForm.java @@ -1,10 +1,10 @@ package automationpractice.forms; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.JavaScript; -import aquality.selenium.elements.ElementState; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.ElementType; -import aquality.selenium.elements.ElementsCount; import aquality.selenium.elements.interfaces.IButton; import aquality.selenium.elements.interfaces.IElement; import aquality.selenium.elements.interfaces.ILabel; @@ -25,7 +25,7 @@ public ProductListForm() { } public List getProductContainerLabels(){ - return getElementFactory().findElements(By.xpath(XPATH_PRODUCT_CONTAINER), ElementType.LABEL, ElementState.DISPLAYED, ElementsCount.MORE_THEN_ZERO); + return getElementFactory().findElements(By.xpath(XPATH_PRODUCT_CONTAINER), ElementType.LABEL, ElementsCount.MORE_THEN_ZERO, ElementState.DISPLAYED); } private ILabel getLblFirstProduct(){ @@ -33,7 +33,7 @@ private ILabel getLblFirstProduct(){ } public ILabel getLblLastProduct(){ - return getElementFactory().getLabel(By.id("homefeatured"), "home featured").findChildElement(By.xpath("//li".concat("[last()]")), ILabel.class); + return getElementFactory().getLabel(By.id("homefeatured"), "home featured").findChildElement(By.xpath(".//li".concat("[last()]")), ILabel.class); } public IButton getBtnLastProductMoreFocused() { @@ -50,7 +50,7 @@ public IButton getBtnLastProductMoreFocused() { public void addToCardRandomProduct(){ List productList = getProductContainerLabels(); ILabel lblProduct = productList.get(new Random().nextInt(productList.size())); - BrowserManager.getBrowser().executeScript(JavaScript.SCROLL_TO_ELEMENT, lblProduct.getElement()); + AqualityServices.getBrowser().executeScript(JavaScript.SCROLL_TO_ELEMENT, lblProduct.getElement()); lblProduct.getMouseActions().moveMouseToElement(); getBtnAddCard(lblProduct).getJsActions().click(); } diff --git a/src/test/java/automationpractice/forms/ShoppingCardSummaryForm.java b/src/test/java/automationpractice/forms/ShoppingCardSummaryForm.java index 76393cb..d868e71 100644 --- a/src/test/java/automationpractice/forms/ShoppingCardSummaryForm.java +++ b/src/test/java/automationpractice/forms/ShoppingCardSummaryForm.java @@ -1,7 +1,7 @@ package automationpractice.forms; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.Attributes; -import aquality.selenium.elements.ElementState; import aquality.selenium.elements.interfaces.IButton; import aquality.selenium.elements.interfaces.ILabel; import aquality.selenium.forms.Form; diff --git a/src/test/java/automationpractice/forms/SliderForm.java b/src/test/java/automationpractice/forms/SliderForm.java index 3cb3598..be5f9f8 100644 --- a/src/test/java/automationpractice/forms/SliderForm.java +++ b/src/test/java/automationpractice/forms/SliderForm.java @@ -1,11 +1,11 @@ package automationpractice.forms; -import aquality.selenium.forms.Form; -import aquality.selenium.elements.ElementsCount; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.ElementType; -import aquality.selenium.elements.ElementState; import aquality.selenium.elements.interfaces.IButton; import aquality.selenium.elements.interfaces.ILabel; +import aquality.selenium.forms.Form; import org.openqa.selenium.By; import org.openqa.selenium.Point; @@ -23,11 +23,11 @@ public SliderForm() { } public List getListElements(ElementState state, ElementsCount elementsCount){ - return getElementFactory().findElements(By.xpath(STR_LIST_ELEMENTS), ElementType.LABEL, state, elementsCount); + return getElementFactory().findElements(By.xpath(STR_LIST_ELEMENTS), ElementType.LABEL, elementsCount, state); } public Point getFormPointInViewPort(){ - return getElementFactory().getLabel(locator, name).getJsActions().getViewPortCoordinates(); + return getElementFactory().getLabel(getLocator(), getName()).getJsActions().getViewPortCoordinates(); } public IButton getBtnAddToCart(ElementState elementState){ diff --git a/src/test/java/automationpractice/forms/YourPersonalInfoForm.java b/src/test/java/automationpractice/forms/YourPersonalInfoForm.java index 032eaf5..2b80fd5 100644 --- a/src/test/java/automationpractice/forms/YourPersonalInfoForm.java +++ b/src/test/java/automationpractice/forms/YourPersonalInfoForm.java @@ -1,11 +1,12 @@ package automationpractice.forms; -import aquality.selenium.elements.ElementState; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.ElementType; -import aquality.selenium.elements.ElementsCount; import aquality.selenium.elements.interfaces.*; import aquality.selenium.forms.Form; import org.openqa.selenium.By; +import org.openqa.selenium.Keys; import java.util.List; @@ -30,10 +31,11 @@ public void selectGender(Integer genderId){ public void setFirstName(String firstName){ txbFirstName.type(firstName); + txbFirstName.sendKeys(Keys.ENTER); } public Integer getNumOfDays(){ - List lblDays = getElementFactory().findElements(By.xpath(XPATH_SELECT_DAYS), ElementType.LABEL, ElementState.EXISTS_IN_ANY_STATE, ElementsCount.MORE_THEN_ZERO); + List lblDays = getElementFactory().findElements(By.xpath(XPATH_SELECT_DAYS), ElementType.LABEL, ElementsCount.MORE_THEN_ZERO, ElementState.EXISTS_IN_ANY_STATE); return lblDays.size(); } diff --git a/src/test/java/tests/BaseTest.java b/src/test/java/tests/BaseTest.java index 91d60c1..643a6d8 100644 --- a/src/test/java/tests/BaseTest.java +++ b/src/test/java/tests/BaseTest.java @@ -1,8 +1,7 @@ package tests; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementFactory; import aquality.selenium.elements.interfaces.IElementFactory; import org.openqa.selenium.Dimension; import org.testng.annotations.AfterMethod; @@ -16,7 +15,7 @@ public abstract class BaseTest { protected final IElementFactory elementFactory; protected BaseTest() { - elementFactory = new ElementFactory(); + elementFactory = AqualityServices.getElementFactory(); } @BeforeMethod @@ -26,15 +25,17 @@ protected void beforeMethod() { } @AfterMethod - public void afterTest(){ - BrowserManager.getBrowser().quit(); + public void afterTest() { + if (AqualityServices.isBrowserStarted()) { + AqualityServices.getBrowser().quit(); + } } protected void navigate(TheInternetPage page) { getBrowser().goTo(page.getAddress()); } - protected Browser getBrowser(){ - return BrowserManager.getBrowser(); + protected Browser getBrowser() { + return AqualityServices.getBrowser(); } } diff --git a/src/test/java/tests/integration/ActionTests.java b/src/test/java/tests/integration/ActionTests.java index 426cb84..c563777 100644 --- a/src/test/java/tests/integration/ActionTests.java +++ b/src/test/java/tests/integration/ActionTests.java @@ -1,11 +1,10 @@ package tests.integration; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.JavaScript; import aquality.selenium.elements.actions.JsActions; import aquality.selenium.elements.interfaces.IButton; import aquality.selenium.elements.interfaces.ITextBox; -import aquality.selenium.waitings.ConditionalWait; import automationpractice.forms.ProductForm; import automationpractice.forms.ProductListForm; import org.openqa.selenium.Keys; @@ -21,9 +20,9 @@ public class ActionTests extends BaseTest { @BeforeMethod @Override protected void beforeMethod() { - BrowserManager.getBrowser().getDriver().manage().window().maximize(); - if (!BrowserManager.getBrowser().getCurrentUrl().equals(URL_AUTOMATIONPRACTICE)) { - BrowserManager.getBrowser().goTo(URL_AUTOMATIONPRACTICE); + AqualityServices.getBrowser().getDriver().manage().window().maximize(); + if (!AqualityServices.getBrowser().getCurrentUrl().equals(URL_AUTOMATIONPRACTICE)) { + AqualityServices.getBrowser().goTo(URL_AUTOMATIONPRACTICE); } } @@ -36,7 +35,7 @@ public void testScrollToTheCenter() { @Test public void testScrollIntoView() { - BrowserManager.getBrowser().executeScript(JavaScript.SCROLL_TO_BOTTOM); + AqualityServices.getBrowser().executeScript(JavaScript.SCROLL_TO_BOTTOM); JsActions jsActions = new ProductListForm().getLblLastProduct().getJsActions(); jsActions.scrollIntoView(); Assert.assertTrue(jsActions.isElementOnScreen(), "element is not on the screen after scrollIntoView()"); @@ -52,7 +51,7 @@ public void testMoveMouseToElement() { public void testMoveMouseFromElement() { ProductListForm productListForm = new ProductListForm(); - Assert.assertTrue(ConditionalWait.waitFor(() -> { + Assert.assertTrue(AqualityServices.getConditionalWait().waitFor(() -> { IButton button = productListForm.getBtnLastProductMoreFocused(); return button.getText().contains("More"); }, "element is not focused after moveMouseToElement()")); diff --git a/src/test/java/tests/integration/AlertTests.java b/src/test/java/tests/integration/AlertTests.java index 198c4da..d26e269 100644 --- a/src/test/java/tests/integration/AlertTests.java +++ b/src/test/java/tests/integration/AlertTests.java @@ -1,7 +1,7 @@ package tests.integration; import aquality.selenium.browser.AlertActions; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import org.openqa.selenium.NoAlertPresentException; import org.testng.Assert; import org.testng.annotations.BeforeMethod; @@ -17,7 +17,7 @@ public class AlertTests extends BaseTest { @BeforeMethod @Override public void beforeMethod() { - BrowserManager.getBrowser().goTo(TheInternetPage.JAVASCRIPT_ALERTS.getAddress()); + AqualityServices.getBrowser().goTo(TheInternetPage.JAVASCRIPT_ALERTS.getAddress()); } @Test diff --git a/src/test/java/tests/integration/BrowserTests.java b/src/test/java/tests/integration/BrowserTests.java index 956c93d..d7034ab 100644 --- a/src/test/java/tests/integration/BrowserTests.java +++ b/src/test/java/tests/integration/BrowserTests.java @@ -1,9 +1,10 @@ package tests.integration; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.BrowserName; import aquality.selenium.browser.JavaScript; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.core.utilities.ISettingsFile; +import aquality.selenium.core.utilities.JsonSettingsFile; import automationpractice.forms.SliderForm; import org.openqa.selenium.*; import org.testng.Assert; @@ -17,6 +18,7 @@ import java.io.IOException; import java.io.UncheckedIOException; +import java.time.Duration; import static automationpractice.Constants.URL_AUTOMATIONPRACTICE; import static utils.FileUtil.getResourceFileByName; @@ -80,7 +82,7 @@ public void testBrowserShouldBePossibleToRefreshPage(){ @Test(expectedExceptions = TimeoutException.class) public void testShouldBePossibleToSetPageLoadTimeout(){ - getBrowser().setPageLoadTimeout(1L); + getBrowser().setPageLoadTimeout(Duration.ofSeconds(1L)); String urlAquality = "https://github.com/aquality-automation"; getBrowser().goTo(urlAquality); } @@ -126,7 +128,7 @@ public void testScriptTimeoutExeceptionShouldBeThrownIfScriptTimeoutIsOver(){ getBrowser().goTo(url); getBrowser().waitForPageToLoad(); - long expectedDurationInSeconds = Configuration.getInstance().getTimeoutConfiguration().getScript() + 1; + long expectedDurationInSeconds = AqualityServices.getConfiguration().getTimeoutConfiguration().getScript().getSeconds() + 1; getBrowser().executeAsyncScript(getAsyncTimeoutJavaScript(expectedDurationInSeconds)); } @@ -175,7 +177,7 @@ public void testShouldBePossibleToScrollWindowBy(){ getBrowser().goTo(URL_AUTOMATIONPRACTICE); SliderForm sliderForm = new SliderForm(); int initialY = sliderForm.getFormPointInViewPort().getY(); - int formHeight = sliderForm.getFormSize().getHeight(); + int formHeight = sliderForm.getSize().getHeight(); getBrowser().scrollWindowBy(0, formHeight); Assert.assertEquals(initialY - sliderForm.getFormPointInViewPort().getY(), formHeight); } @@ -189,7 +191,7 @@ public void testShouldBePossibleToGetBrowserName() { @Test public void testShouldBePossibleToSetImplicitWait(){ long waitTime = 5L; - getBrowser().setImplicitWaitTimeout(waitTime); + getBrowser().setImplicitWaitTimeout(Duration.ofSeconds(waitTime)); Timer timer = new Timer(); timer.start(); @@ -199,6 +201,7 @@ public void testShouldBePossibleToSetImplicitWait(){ }catch (NoSuchElementException e){ durationSample = new DurationSample(timer.duration(), waitTime, defaultDeviation); } + Assert.assertNotNull(durationSample); Assert.assertTrue(durationSample.isDurationBetweenLimits(), durationSample.toString()); } @@ -207,10 +210,10 @@ public void testShouldBePossibleToGetDownloadDir(){ Assert.assertFalse(getBrowser().getDownloadDirectory().isEmpty(), "Browser download directory should not be empty " + getBrowser().getDownloadDirectory()); } - private JsonFile getSettings() { + private ISettingsFile getSettings() { String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json"; try { - return new JsonFile(getResourceFileByName(settingsProfile)); + return new JsonSettingsFile(getResourceFileByName(settingsProfile)); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/src/test/java/tests/integration/ElementStateTests.java b/src/test/java/tests/integration/ElementStateTests.java index 904ca2b..c1eea4d 100644 --- a/src/test/java/tests/integration/ElementStateTests.java +++ b/src/test/java/tests/integration/ElementStateTests.java @@ -1,7 +1,7 @@ package tests.integration; -import aquality.selenium.configuration.Configuration; -import aquality.selenium.elements.ElementFactory; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.elements.interfaces.IElementFactory; import aquality.selenium.elements.interfaces.ILabel; import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; @@ -14,18 +14,20 @@ import utils.DurationSample; import utils.Timer; +import java.time.Duration; + public class ElementStateTests extends BaseTest { - private final long customWaitTime = 2L; + private final Duration customWaitTime = Duration.ofSeconds(2L); private final double customDeviation = 2; private final double defaultDeviation = 7; - private final ElementFactory elementFactory = new ElementFactory(); + private final IElementFactory elementFactory = AqualityServices.get(IElementFactory.class); private final ILabel lblNotExists = elementFactory.getLabel(By.xpath("//div[@class='not exist element']"), "not exist element"); @Test public void testElementShouldWaitForEnabledWithCustomTimeout() { navigate(TheInternetPage.DYNAMIC_CONTROLS); - long waitTime = customWaitTime; + Duration waitTime = customWaitTime; Timer timer = new Timer(); timer.start(); @@ -39,7 +41,7 @@ public void testElementShouldWaitForEnabledWithCustomTimeout() { @Test public void testElementShouldWaitForEnabledWithDefaultTimeout() { navigate(TheInternetPage.DYNAMIC_CONTROLS); - long waitTime = Configuration.getInstance().getTimeoutConfiguration().getCondition(); + long waitTime = AqualityServices.getConfiguration().getTimeoutConfiguration().getCondition().getSeconds(); Timer timer = new Timer(); timer.start(); @@ -53,7 +55,7 @@ public void testElementShouldWaitForEnabledWithDefaultTimeout() { @Test public void testElementShouldWaitForNotEnabledWithCustomTimeout() { navigate(TheInternetPage.DYNAMIC_CONTROLS); - long waitTime = customWaitTime; + Duration waitTime = customWaitTime; DynamicControlsForm dynamicControlsForm = new DynamicControlsForm(); dynamicControlsForm.getBtnEnable().click(); @@ -81,7 +83,7 @@ public void testNoSuchShouldBeThrownForWaitNotEnabledIfElementNotFound(){ @Test public void testElementShouldWaitForNotEnabledWithDefaultTimeout() { navigate(TheInternetPage.DYNAMIC_CONTROLS); - long waitTime = Configuration.getInstance().getTimeoutConfiguration().getCondition(); + long waitTime = AqualityServices.getConfiguration().getTimeoutConfiguration().getCondition().getSeconds(); DynamicControlsForm dynamicControlsForm = new DynamicControlsForm(); dynamicControlsForm.getBtnEnable().click(); @@ -119,7 +121,7 @@ public void testWaitForExist(){ public void testShouldBePossibleToWaitElementNotExistsCustom(){ navigate(TheInternetPage.DYNAMIC_CONTROLS); DynamicControlsForm dynamicControlsForm = new DynamicControlsForm(); - long waitTime = customWaitTime; + Duration waitTime = customWaitTime; dynamicControlsForm.getBtnRemove().click(); Timer timer = new Timer(); @@ -135,7 +137,7 @@ public void testShouldBePossibleToWaitElementNotExistsCustom(){ public void testShouldBePossibleToWaitElementNotExists(){ navigate(TheInternetPage.DYNAMIC_CONTROLS); DynamicControlsForm dynamicControlsForm = new DynamicControlsForm(); - long waitTime = Configuration.getInstance().getTimeoutConfiguration().getCondition(); + long waitTime = AqualityServices.getConfiguration().getTimeoutConfiguration().getCondition().getSeconds(); dynamicControlsForm.getBtnRemove().click(); Timer timer = new Timer(); diff --git a/src/test/java/tests/integration/ElementTests.java b/src/test/java/tests/integration/ElementTests.java index 0e956d8..2e5bc4d 100644 --- a/src/test/java/tests/integration/ElementTests.java +++ b/src/test/java/tests/integration/ElementTests.java @@ -1,13 +1,11 @@ package tests.integration; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementState; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.ElementType; -import aquality.selenium.elements.ElementsCount; import aquality.selenium.elements.HighlightState; import aquality.selenium.elements.interfaces.*; -import theinternet.forms.FormAuthenticationForm; -import aquality.selenium.waitings.ConditionalWait; import automationpractice.forms.DropDownForm; import org.openqa.selenium.By; import org.openqa.selenium.Keys; @@ -18,6 +16,7 @@ import org.testng.asserts.SoftAssert; import tests.BaseTest; import theinternet.TheInternetPage; +import theinternet.forms.FormAuthenticationForm; import java.util.List; @@ -37,7 +36,7 @@ public void testComboBox() { String selectedText = comboBox.getSelectedText(); comboBox.selectByText("Option 2"); - ConditionalWait.waitFor(y -> !selectedText.equals(comboBox.getSelectedText()), "Combobox should not be equal to " + selectedText); + AqualityServices.getConditionalWait().waitFor(y -> !selectedText.equals(comboBox.getSelectedText()), "Combobox should not be equal to " + selectedText); Assert.assertEquals(comboBox.getJsActions().getSelectedText(), texts.get(2)); } @@ -84,7 +83,7 @@ public void testCheckBox() { navigate(TheInternetPage.CHECKBOXES); String checkboxLocator = "//input[@type='checkbox']"; List checkBoxes = elementFactory.findElements(By.xpath(checkboxLocator), ICheckBox.class, - ElementState.DISPLAYED, ElementsCount.MORE_THEN_ZERO); + ElementsCount.MORE_THEN_ZERO, ElementState.DISPLAYED); ICheckBox checkBox1 = checkBoxes.get(0); ICheckBox checkBox2 = checkBoxes.get(1); boolean stateFirst = checkBox1.isChecked(); @@ -96,7 +95,7 @@ public void testCheckBox() { checkBox2.uncheck(); Assert.assertFalse(checkBox2.isChecked()); - BrowserManager.getBrowser().refresh(); + AqualityServices.getBrowser().refresh(); checkBoxes = elementFactory.findElements(By.xpath(checkboxLocator), ElementType.CHECKBOX); checkBox1 = checkBoxes.get(0); checkBox2 = checkBoxes.get(1); @@ -111,19 +110,19 @@ public void testLink() { String href = link.getHref(); link.click(); String expectedUrl = TheInternetPage.STATUS_CODES.getAddress(); - ExpectedCondition statusCodesExpectedCondition = webDriver -> BrowserManager.getBrowser().getCurrentUrl().equalsIgnoreCase(expectedUrl); - ConditionalWait.waitFor(statusCodesExpectedCondition, "Current url should be equal to " + expectedUrl); - Assert.assertEquals(BrowserManager.getBrowser().getCurrentUrl(), TheInternetPage.STATUS_CODES.getAddress()); + ExpectedCondition statusCodesExpectedCondition = webDriver -> AqualityServices.getBrowser().getCurrentUrl().equalsIgnoreCase(expectedUrl); + AqualityServices.getConditionalWait().waitFor(statusCodesExpectedCondition, "Current url should be equal to " + expectedUrl); + Assert.assertEquals(AqualityServices.getBrowser().getCurrentUrl(), TheInternetPage.STATUS_CODES.getAddress()); - BrowserManager.getBrowser().goBack(); + AqualityServices.getBrowser().goBack(); link = elementFactory.getLink(By.id("redirect"), "Link", ElementState.DISPLAYED); link.click(); - ConditionalWait.waitFor(statusCodesExpectedCondition, "Current url should be equal to " + expectedUrl); - Assert.assertEquals(BrowserManager.getBrowser().getCurrentUrl(), TheInternetPage.STATUS_CODES.getAddress()); + AqualityServices.getConditionalWait().waitFor(statusCodesExpectedCondition, "Current url should be equal to " + expectedUrl); + Assert.assertEquals(AqualityServices.getBrowser().getCurrentUrl(), TheInternetPage.STATUS_CODES.getAddress()); - BrowserManager.getBrowser().getDriver().navigate().to(href); - ConditionalWait.waitFor(statusCodesExpectedCondition,"Current url should be equal to " + expectedUrl); - Assert.assertEquals(BrowserManager.getBrowser().getCurrentUrl(), TheInternetPage.STATUS_CODES.getAddress()); + AqualityServices.getBrowser().getDriver().navigate().to(href); + AqualityServices.getConditionalWait().waitFor(statusCodesExpectedCondition,"Current url should be equal to " + expectedUrl); + Assert.assertEquals(AqualityServices.getBrowser().getCurrentUrl(), TheInternetPage.STATUS_CODES.getAddress()); } @Test @@ -143,7 +142,7 @@ public void testTextBox() { txbPass.submit(); String expectedValue = ""; - boolean result = ConditionalWait.waitFor(() -> txbPass.getValue().equalsIgnoreCase(expectedValue), "Value of textbox should be equal " + expectedValue); + boolean result = AqualityServices.getConditionalWait().waitFor(() -> txbPass.getValue().equalsIgnoreCase(expectedValue), "Value of textbox should be equal " + expectedValue); softAssert.assertTrue(result); softAssert.assertAll(); } @@ -165,7 +164,7 @@ public void testSetInnerHtml() { @Test public void testRightClick() { - BrowserManager.getBrowser().getDriver().navigate().to("https://swisnl.github.io/jQuery-contextMenu/demo.html"); + AqualityServices.getBrowser().getDriver().navigate().to("https://swisnl.github.io/jQuery-contextMenu/demo.html"); ILabel label = elementFactory.getLabel(By.xpath("//span[contains(@class, 'context')]"), "Right click"); label.getMouseActions().rightClick(); boolean present = elementFactory.getLabel(By.xpath("//ul[contains(@class, 'context-menu-list')]"), "List", ElementState.DISPLAYED).state().waitForDisplayed(); diff --git a/src/test/java/tests/integration/HiddenElementsTests.java b/src/test/java/tests/integration/HiddenElementsTests.java index 00fe5a3..fb9b24a 100644 --- a/src/test/java/tests/integration/HiddenElementsTests.java +++ b/src/test/java/tests/integration/HiddenElementsTests.java @@ -1,8 +1,8 @@ package tests.integration; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementState; -import aquality.selenium.elements.ElementsCount; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.interfaces.ILabel; import automationpractice.forms.SliderForm; import org.testng.Assert; @@ -19,7 +19,7 @@ public class HiddenElementsTests extends BaseTest { @BeforeMethod @Override protected void beforeMethod() { - BrowserManager.getBrowser().goTo(URL_AUTOMATIONPRACTICE); + AqualityServices.getBrowser().goTo(URL_AUTOMATIONPRACTICE); } @Test diff --git a/src/test/java/tests/usecases/BrowserConcurrencyTests.java b/src/test/java/tests/usecases/BrowserConcurrencyTests.java index 6aa127c..303b082 100644 --- a/src/test/java/tests/usecases/BrowserConcurrencyTests.java +++ b/src/test/java/tests/usecases/BrowserConcurrencyTests.java @@ -1,8 +1,7 @@ package tests.usecases; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementFactory; import aquality.selenium.elements.ElementType; import aquality.selenium.elements.HighlightState; import aquality.selenium.elements.interfaces.ILabel; @@ -34,13 +33,13 @@ public void testBrowserShouldBePossibleToHaveTwoBrowsersForTwoThreads() throws I @Test public void testShouldBePossibleToUseParallelStreams(){ - Browser browser = BrowserManager.getBrowser(); + Browser browser = AqualityServices.getBrowser(); browser.goTo(TheInternetPage.TABLES.getAddress()); - List textBoxes = new ElementFactory().findElements(By.xpath("//td"), ElementType.LABEL); + List textBoxes = AqualityServices.getElementFactory().findElements(By.xpath("//td"), ElementType.LABEL); List texts = new ArrayList<>(); textBoxes.parallelStream().forEach(lbl -> { // set the same instance of browser for all threads - BrowserManager.setBrowser(browser); + AqualityServices.setBrowser(browser); String text = lbl.getText(HighlightState.HIGHLIGHT); // processing results of work trough web driver (getting text) String updatedText = text + "_updated"; @@ -59,9 +58,9 @@ class BrowserThread implements Runnable } @Override public void run() { - BrowserManager.getBrowser().goTo(url); - Assert.assertEquals(url, BrowserManager.getBrowser().getCurrentUrl()); - BrowserManager.getBrowser().quit(); + AqualityServices.getBrowser().goTo(url); + Assert.assertEquals(url, AqualityServices.getBrowser().getCurrentUrl()); + AqualityServices.getBrowser().quit(); } } } diff --git a/src/test/java/tests/usecases/BrowserFactoryTests.java b/src/test/java/tests/usecases/BrowserFactoryTests.java index c147156..9970997 100644 --- a/src/test/java/tests/usecases/BrowserFactoryTests.java +++ b/src/test/java/tests/usecases/BrowserFactoryTests.java @@ -1,20 +1,14 @@ package tests.usecases; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.browser.BrowserName; +import aquality.selenium.browser.BrowserModule; import aquality.selenium.browser.IBrowserFactory; -import aquality.selenium.configuration.*; -import aquality.selenium.configuration.driversettings.ChromeSettings; +import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.driversettings.FirefoxSettings; -import aquality.selenium.configuration.driversettings.IDriverSettings; -import aquality.selenium.utils.JsonFile; -import aquality.selenium.waitings.ConditionalWait; -import com.google.common.util.concurrent.UncheckedExecutionException; +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Provider; import io.github.bonigarcia.wdm.WebDriverManager; -import org.openqa.selenium.InvalidArgumentException; -import org.openqa.selenium.StaleElementReferenceException; -import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.AfterMethod; @@ -24,54 +18,47 @@ import java.io.File; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; +import java.time.Duration; import java.util.Comparator; import java.util.stream.Stream; public class BrowserFactoryTests { - private final String downloadDirFactoryInitialized = "./target/downloads_custom/"; - private final JsonFile jsonProfile; - - public BrowserFactoryTests() { - String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json"; - this.jsonProfile = new JsonFile(settingsProfile); - } - @Test public void testShouldBePossibleToSetBrowser() { - - IBrowserFactory webDriverFactory = () -> { - FirefoxSettings firefoxSettings = new FirefoxSettings(jsonProfile); - WebDriverManager.firefoxdriver().setup(); - FirefoxDriver driver = new FirefoxDriver(firefoxSettings.getCapabilities()); - return new Browser(driver, new CustomConfiguration(BrowserName.FIREFOX, firefoxSettings, Configuration.getInstance().getTimeoutConfiguration())); - }; - - BrowserManager.setBrowser(webDriverFactory.getBrowser()); - BrowserManager.getBrowser().goTo(TheInternetPage.LOGIN.getAddress()); - Assert.assertEquals(BrowserManager.getBrowser().getDriver().getCapabilities().getBrowserName(), "firefox"); + AqualityServices.setBrowser(getCustomFactory().getBrowser()); + AqualityServices.getBrowser().goTo(TheInternetPage.LOGIN.getAddress()); + Assert.assertEquals(AqualityServices.getBrowser().getDriver().getCapabilities().getBrowserName(), "firefox"); } @Test public void testShouldBePossibleToSetFactory() { - IBrowserFactory webDriverFactory = new ACustomLocalFactory(); - BrowserManager.setFactory(webDriverFactory); - Assert.assertEquals(BrowserManager.getBrowser().getDownloadDirectory(), new CustomChromeSettings(jsonProfile).getDownloadDir()); + IBrowserFactory customFactory = getCustomFactory(); + AqualityServices.setBrowserFactory(customFactory); + Assert.assertEquals(customFactory, AqualityServices.getBrowserFactory()); + Assert.assertEquals(AqualityServices.getBrowser().getDriver().getCapabilities().getBrowserName(), "firefox"); + } + + private IBrowserFactory getCustomFactory() { + return () -> { + FirefoxSettings firefoxSettings = new FirefoxSettings(AqualityServices.get(ISettingsFile.class)); + WebDriverManager.firefoxdriver().setup(); + FirefoxDriver driver = new FirefoxDriver(firefoxSettings.getCapabilities().setHeadless(true)); + return new Browser(driver); + }; } @Test public void testShouldBePossibleToOverrideDownloadDirectory() throws IOException { - IBrowserFactory webDriverFactory = new ACustomLocalFactory(); - BrowserManager.setFactory(webDriverFactory); - String downloadDir = BrowserManager.getBrowser().getDownloadDirectory(); - if (new File(downloadDirFactoryInitialized).exists()){ + String downloadDirInitialized = CustomBrowserProfile.getDownloadDirInitialized(); + AqualityServices.initInjector(new CustomBrowserModule(AqualityServices::getBrowser)); + + String downloadDir = AqualityServices.getBrowser().getDownloadDirectory(); + if (new File(downloadDirInitialized).exists()) { try (Stream walk = Files.walk(Paths.get(downloadDir))) { walk.sorted(Comparator.reverseOrder()) .map(Path::toFile) @@ -82,135 +69,28 @@ public void testShouldBePossibleToOverrideDownloadDirectory() throws IOException String fileName = new FileDownloaderForm().getFileName(); String urlXlsSample = TheInternetPage.DOWNLOAD.getAddress() + "/" + fileName; - BrowserManager.getBrowser().goTo(urlXlsSample); - File fileDownloaded = new File(downloadDirFactoryInitialized + fileName); - boolean isFileDownloaded = ConditionalWait.waitFor(driver -> fileDownloaded.exists(), 120, 300, "File should be downloaded"); + AqualityServices.getBrowser().goTo(urlXlsSample); + File fileDownloaded = new File(downloadDirInitialized + fileName); + boolean isFileDownloaded = AqualityServices.getConditionalWait().waitFor(driver -> fileDownloaded.exists(), + Duration.ofSeconds(120), Duration.ofMillis(300), "File should be downloaded"); Assert.assertTrue(isFileDownloaded, "Downloaded file exists"); } - private class ACustomLocalFactory implements IBrowserFactory { + private class CustomBrowserModule extends BrowserModule { - @Override - public Browser getBrowser() { - WebDriverManager.chromedriver().setup(); - CustomChromeSettings chromeSettings = new CustomChromeSettings(jsonProfile); - ChromeDriver driver = new ChromeDriver(chromeSettings.getCapabilities()); - return new Browser(driver, new CustomConfiguration(BrowserName.CHROME, chromeSettings, new ITimeoutConfiguration() { - @Override - public long getImplicit() { - return 0; - } - - @Override - public long getCondition() { - return 30; - } - - @Override - public long getScript() { - return 10; - } - - @Override - public long getPageLoad() { - return 10; - } - - @Override - public long getPollingInterval() { - return 300; - } - - @Override - public long getCommand() { - return 120; - } - })); - } - } - - private class CustomChromeSettings extends ChromeSettings { - - CustomChromeSettings(JsonFile jsonFile) { - super(jsonFile); - } - - @Override - public String getDownloadDir() { - try { - return new File(downloadDirFactoryInitialized).getCanonicalPath(); - } - catch (IOException e) { - throw new InvalidArgumentException(e.getMessage()); - } - } - } - - private class CustomConfiguration implements IConfiguration{ - - private final IDriverSettings driverSettings; - private final ITimeoutConfiguration timeoutConfiguration; - private final BrowserName browserName; - - CustomConfiguration(BrowserName browserName, IDriverSettings driverSettings, ITimeoutConfiguration timeoutConfiguration){ - this.driverSettings = driverSettings; - this.timeoutConfiguration = timeoutConfiguration; - this.browserName = browserName; - } - - @Override - public IBrowserProfile getBrowserProfile() { - return new IBrowserProfile() { - @Override - public BrowserName getBrowserName() { - return browserName; - } - - @Override - public boolean isRemote() { - return false; - } - - @Override - public boolean isElementHighlightEnabled() { - return false; - } - - @Override - public IDriverSettings getDriverSettings() { - return driverSettings; - } - - @Override - public URL getRemoteConnectionUrl() { - try { - return new URL(jsonProfile.getValue("/remoteConnectionUrl").toString()); - } catch (MalformedURLException e) { - throw new UncheckedExecutionException(e); - } - } - }; - } - - @Override - public ITimeoutConfiguration getTimeoutConfiguration() { - return timeoutConfiguration; - } - - @Override - public IRetryConfiguration getRetryConfiguration() { - return null; + CustomBrowserModule(Provider applicationProvider) { + super(applicationProvider); } @Override - public ILoggerConfiguration getLoggerConfiguration() { - return null; + public Class getBrowserProfileImplementation() { + return CustomBrowserProfile.class; } } @AfterMethod - public void afterMethod(){ - BrowserManager.getBrowser().quit(); - BrowserManager.setDefaultFactory(); + public void afterMethod() { + AqualityServices.getBrowser().quit(); + AqualityServices.setDefaultBrowserFactory(); } } diff --git a/src/test/java/tests/usecases/CustomBrowserProfile.java b/src/test/java/tests/usecases/CustomBrowserProfile.java new file mode 100644 index 0000000..f15de8e --- /dev/null +++ b/src/test/java/tests/usecases/CustomBrowserProfile.java @@ -0,0 +1,53 @@ +package tests.usecases; + +import aquality.selenium.configuration.BrowserProfile; +import aquality.selenium.configuration.driversettings.ChromeSettings; +import aquality.selenium.configuration.driversettings.IDriverSettings; +import aquality.selenium.core.utilities.ISettingsFile; +import com.google.inject.Inject; +import org.openqa.selenium.InvalidArgumentException; + +import java.io.File; +import java.io.IOException; + +public class CustomBrowserProfile extends BrowserProfile { + private static final String downloadDirInitialized = "./target/downloads_custom/"; + + static String getDownloadDirInitialized() { + return downloadDirInitialized; + } + + private final ISettingsFile settingsFile; + + @Inject + public CustomBrowserProfile(ISettingsFile settingsFile) { + super(settingsFile); + this.settingsFile = settingsFile; + } + + @Override + public boolean isRemote() { + return false; + } + + @Override + public IDriverSettings getDriverSettings() { + return new CustomChromeSettings(settingsFile); + } + + private class CustomChromeSettings extends ChromeSettings { + + CustomChromeSettings(ISettingsFile jsonFile) { + super(jsonFile); + } + + @Override + public String getDownloadDir() { + try { + return new File(downloadDirInitialized).getCanonicalPath(); + } catch (IOException e) { + throw new InvalidArgumentException(e.getMessage()); + } + } + } +} diff --git a/src/test/java/tests/usecases/CustomElementTests.java b/src/test/java/tests/usecases/CustomElementTests.java index 2dc2efd..4031c17 100644 --- a/src/test/java/tests/usecases/CustomElementTests.java +++ b/src/test/java/tests/usecases/CustomElementTests.java @@ -1,8 +1,7 @@ package tests.usecases; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementFactory; -import aquality.selenium.elements.ElementState; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.TextBox; import aquality.selenium.elements.interfaces.ITextBox; import org.openqa.selenium.By; @@ -16,11 +15,11 @@ public class CustomElementTests extends BaseTest { @Test public void testCustomTextBox() { - BrowserManager.getBrowser().goTo(TheInternetPage.LOGIN.getAddress()); + AqualityServices.getBrowser().goTo(TheInternetPage.LOGIN.getAddress()); FormAuthenticationForm authenticationForm = new FormAuthenticationForm(); ITextBox txbUsername = authenticationForm.getTxbUsername(); - CustomTextBox customTxbUsername = new ElementFactory() + CustomTextBox customTxbUsername = AqualityServices.getElementFactory() .getCustomElement(CustomTextBox::new, txbUsername.getLocator(), txbUsername.getName(), ElementState.EXISTS_IN_ANY_STATE); txbUsername.type("wrong"); customTxbUsername.type("right"); diff --git a/src/test/java/tests/usecases/ElementExistNotDisplayedTest.java b/src/test/java/tests/usecases/ElementExistNotDisplayedTest.java index 7e46622..2a4c657 100644 --- a/src/test/java/tests/usecases/ElementExistNotDisplayedTest.java +++ b/src/test/java/tests/usecases/ElementExistNotDisplayedTest.java @@ -1,9 +1,8 @@ package tests.usecases; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementState; +import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.IButton; -import aquality.selenium.waitings.ConditionalWait; import automationpractice.forms.SliderForm; import org.testng.Assert; import org.testng.annotations.BeforeMethod; @@ -17,12 +16,12 @@ public class ElementExistNotDisplayedTest extends BaseTest { @BeforeMethod @Override public void beforeMethod() { - BrowserManager.getBrowser().goTo(URL_AUTOMATIONPRACTICE); + AqualityServices.getBrowser().goTo(URL_AUTOMATIONPRACTICE); } @Test public void testElementExistNotDisplayed() { IButton button = new SliderForm().getBtnAddToCart(ElementState.EXISTS_IN_ANY_STATE); - Assert.assertTrue(ConditionalWait.waitFor(() -> button.state().isExist() && !button.state().isDisplayed(), "Button should exists in the DOM but should not be displayed ")); + Assert.assertTrue(AqualityServices.getConditionalWait().waitFor(() -> button.state().isExist() && !button.state().isDisplayed(), "Button should exists in the DOM but should not be displayed ")); } } diff --git a/src/test/java/tests/usecases/FileDownloadingTests.java b/src/test/java/tests/usecases/FileDownloadingTests.java index d98f45e..dfff9e2 100644 --- a/src/test/java/tests/usecases/FileDownloadingTests.java +++ b/src/test/java/tests/usecases/FileDownloadingTests.java @@ -1,8 +1,7 @@ package tests.usecases; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.elements.interfaces.ILabel; -import aquality.selenium.waitings.ConditionalWait; import org.openqa.selenium.By; import org.testng.Assert; import org.testng.annotations.Test; @@ -28,14 +27,14 @@ public void testDownloading() { ILabel lblFileContent = elementFactory.getLabel(By.xpath("//pre"), "text file content"); Assert.assertFalse(FileUtil.isFileDownloaded(fileAddress, lblFileContent), "file should not exist before downloading"); - BrowserManager.getBrowser().executeScript(String.format("window.open('%s', '_blank')", TheInternetPage.DOWNLOAD.getAddress())); - ArrayList tabs = new ArrayList<>(BrowserManager.getBrowser().getDriver().getWindowHandles()); + AqualityServices.getBrowser().executeScript(String.format("window.open('%s', '_blank')", TheInternetPage.DOWNLOAD.getAddress())); + ArrayList tabs = new ArrayList<>(AqualityServices.getBrowser().getDriver().getWindowHandles()); - BrowserManager.getBrowser().getDriver().switchTo().window(tabs.get(1)); - BrowserManager.getBrowser().goTo(TheInternetPage.DOWNLOAD.getAddress()); + AqualityServices.getBrowser().getDriver().switchTo().window(tabs.get(1)); + AqualityServices.getBrowser().goTo(TheInternetPage.DOWNLOAD.getAddress()); downloaderForm.getLnkDownload(fileName).getJsActions().clickAndWait(); - BrowserManager.getBrowser().getDriver().switchTo().window(tabs.get(0)); - Assert.assertTrue(ConditionalWait.waitFor(() -> FileUtil.isFileDownloaded(fileAddress, lblFileContent), String.format("File %1$s should be downloaded", fileAddress))); + AqualityServices.getBrowser().getDriver().switchTo().window(tabs.get(0)); + Assert.assertTrue(AqualityServices.getConditionalWait().waitFor(() -> FileUtil.isFileDownloaded(fileAddress, lblFileContent), String.format("File %1$s should be downloaded", fileAddress))); } } \ No newline at end of file diff --git a/src/test/java/tests/usecases/QuickStartExample.java b/src/test/java/tests/usecases/QuickStartExample.java index 55b8319..c87a73e 100644 --- a/src/test/java/tests/usecases/QuickStartExample.java +++ b/src/test/java/tests/usecases/QuickStartExample.java @@ -1,8 +1,8 @@ package tests.usecases; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.elements.ElementFactory; +import aquality.selenium.elements.interfaces.IElementFactory; import aquality.selenium.elements.interfaces.ITextBox; import org.openqa.selenium.By; import org.testng.annotations.Test; @@ -11,13 +11,13 @@ public class QuickStartExample { @Test public void test(){ - Browser browser = BrowserManager.getBrowser(); + Browser browser = AqualityServices.getBrowser(); browser.maximize(); browser.goTo("https://wikipedia.org"); browser.waitForPageToLoad(); - ElementFactory elementFactory = new ElementFactory(); + IElementFactory elementFactory = AqualityServices.getElementFactory(); ITextBox txbSearch = elementFactory.getTextBox(By.id("searchInput"), "Search"); txbSearch.type("quality assurance"); txbSearch.submit(); diff --git a/src/test/java/tests/usecases/ShoppingCartTest.java b/src/test/java/tests/usecases/ShoppingCartTest.java index fdc0c5e..aa18b9c 100644 --- a/src/test/java/tests/usecases/ShoppingCartTest.java +++ b/src/test/java/tests/usecases/ShoppingCartTest.java @@ -1,6 +1,6 @@ package tests.usecases; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.elements.interfaces.ILabel; import automationpractice.forms.*; import automationpractice.modals.ProceedToCheckoutModal; @@ -20,11 +20,11 @@ public class ShoppingCartTest extends BaseTest { @Test public void testShoppingCart() { - BrowserManager.getBrowser().getDriver().navigate().to(URL_AUTOMATIONPRACTICE); + AqualityServices.getBrowser().getDriver().navigate().to(URL_AUTOMATIONPRACTICE); SoftAssert softAssert = new SoftAssert(); SliderForm sliderForm = new SliderForm(); - Assert.assertTrue(sliderForm.isFormDisplayed()); + Assert.assertTrue(sliderForm.isDisplayed()); sliderForm.clickBtnNext(); sliderForm.clickBtnNext(); @@ -42,7 +42,7 @@ public void testShoppingCart() { softAssert.assertEquals(expectedQuantity, actualQuantity, "Quantity is not correct"); shoppingCardSummaryForm.clickProceedToCheckoutBtn(); - softAssert.assertTrue(new AuthenticationForm().isFormDisplayed()); + softAssert.assertTrue(new AuthenticationForm().isDisplayed()); CartMenuForm cartMenuForm = new CartMenuForm(); cartMenuForm.openCartMenu(); cartMenuForm.clickCheckoutBtn(); diff --git a/src/test/java/tests/usecases/TestTimeoutConfiguration.java b/src/test/java/tests/usecases/TestTimeoutConfiguration.java index 7ddb9d1..ac11d88 100644 --- a/src/test/java/tests/usecases/TestTimeoutConfiguration.java +++ b/src/test/java/tests/usecases/TestTimeoutConfiguration.java @@ -1,9 +1,7 @@ package tests.usecases; -import aquality.selenium.browser.Browser; -import aquality.selenium.browser.BrowserManager; -import aquality.selenium.configuration.*; -import aquality.selenium.utils.JsonFile; +import aquality.selenium.configuration.TimeoutConfiguration; +import aquality.selenium.core.utilities.JsonSettingsFile; import org.testng.Assert; import org.testng.annotations.Test; @@ -12,30 +10,6 @@ public class TestTimeoutConfiguration { @Test public void testNumberFormatExceptionShouldBeThrownIfTimeoutIsNotANumber() { Assert.assertThrows(NumberFormatException.class, () -> - { - BrowserManager.setBrowser(new Browser(null, configuration)); - }); + new TimeoutConfiguration(new JsonSettingsFile("settings.incorrect.json"))); } - - IConfiguration configuration = new IConfiguration() { - @Override - public IBrowserProfile getBrowserProfile() { - return Configuration.getInstance().getBrowserProfile(); - } - - @Override - public ITimeoutConfiguration getTimeoutConfiguration() { - return new TimeoutConfiguration(new JsonFile("settings.incorrect.json")); - } - - @Override - public IRetryConfiguration getRetryConfiguration() { - return Configuration.getInstance().getRetryConfiguration(); - } - - @Override - public ILoggerConfiguration getLoggerConfiguration() { - return Configuration.getInstance().getLoggerConfiguration(); - } - }; } diff --git a/src/test/java/theinternet/forms/DynamicLoadingForm.java b/src/test/java/theinternet/forms/DynamicLoadingForm.java index 241b58c..952a0b0 100644 --- a/src/test/java/theinternet/forms/DynamicLoadingForm.java +++ b/src/test/java/theinternet/forms/DynamicLoadingForm.java @@ -5,9 +5,11 @@ import aquality.selenium.elements.interfaces.ILabel; import org.openqa.selenium.By; +import java.time.Duration; + public class DynamicLoadingForm extends Form { - private static final long DEFAULT_LOADING_TIMEOUT = 5L; + private static final Duration DEFAULT_LOADING_TIMEOUT = Duration.ofSeconds(5L); private final IButton btnStart = getElementFactory().getButton(By.xpath("//div[@id='start']/button"), "Start"); private final ILabel lblLoading = getElementFactory().getLabel(By.id("loading"), "loading"); @@ -25,7 +27,7 @@ public IButton getBtnStart() { return btnStart; } - public long getTimeout() { + public Duration getTimeout() { return DEFAULT_LOADING_TIMEOUT; } diff --git a/src/test/java/theinternet/forms/FormAuthenticationForm.java b/src/test/java/theinternet/forms/FormAuthenticationForm.java index fb241e2..947d3da 100644 --- a/src/test/java/theinternet/forms/FormAuthenticationForm.java +++ b/src/test/java/theinternet/forms/FormAuthenticationForm.java @@ -1,17 +1,19 @@ package theinternet.forms; -import aquality.selenium.elements.ElementState; +import aquality.selenium.core.elements.ElementState; import aquality.selenium.elements.interfaces.ILabel; import aquality.selenium.elements.interfaces.ITextBox; import org.openqa.selenium.By; +import java.time.Duration; + public class FormAuthenticationForm extends TheInternetForm { public FormAuthenticationForm() { super(By.id("login"), "login"); } - private static final long DEFAULT_LOADING_TIMEOUT = 5L; + private static final Duration DEFAULT_LOADING_TIMEOUT = Duration.ofSeconds(5L); private static final String XPATH_FORM_LOGIN = "//form[@id='login']"; private final ITextBox txbUsername = getElementFactory().getTextBox(By.id("username"), "username"); @@ -34,7 +36,7 @@ public ITextBox getTxbPassword() { return txbPassword; } - public long getTimeout() { + public Duration getTimeout() { return DEFAULT_LOADING_TIMEOUT; } diff --git a/src/test/java/utils/DurationSample.java b/src/test/java/utils/DurationSample.java index 662b35d..c89090a 100644 --- a/src/test/java/utils/DurationSample.java +++ b/src/test/java/utils/DurationSample.java @@ -1,5 +1,7 @@ package utils; +import java.time.Duration; + public class DurationSample { private final double duration; @@ -7,18 +9,26 @@ public class DurationSample { private final double maxLimit; private final double deviation; - public DurationSample(double duration, double minLimit, double maxLimit, double deviation) { + public DurationSample(double duration, Duration minLimit, Duration maxLimit, double deviation) { this.duration = duration; - this.minLimit = minLimit; - this.maxLimit = maxLimit; + this.minLimit = minLimit.getSeconds(); + this.maxLimit = maxLimit.getSeconds(); this.deviation = deviation; } - public DurationSample(double duration, double expectedDuration, double deviation) { + public DurationSample(double duration, Duration expectedDuration, double deviation) { this(duration, expectedDuration, expectedDuration, deviation); } - public DurationSample(double duration, double expectedDuration) { + public DurationSample(double duration, long expectedDuration, double deviation) { + this(duration, Duration.ofSeconds(expectedDuration), deviation); + } + + public DurationSample(double duration, long expectedDuration) { + this(duration, Duration.ofSeconds(expectedDuration)); + } + + public DurationSample(double duration, Duration expectedDuration) { this(duration, expectedDuration, expectedDuration, 0); } diff --git a/src/test/java/utils/FileUtil.java b/src/test/java/utils/FileUtil.java index 23d258c..f0333f0 100644 --- a/src/test/java/utils/FileUtil.java +++ b/src/test/java/utils/FileUtil.java @@ -1,8 +1,8 @@ package utils; -import aquality.selenium.browser.BrowserManager; +import aquality.selenium.browser.AqualityServices; import aquality.selenium.elements.interfaces.ILabel; -import aquality.selenium.logger.Logger; +import aquality.selenium.core.logging.Logger; import org.openqa.selenium.WebDriverException; import java.io.File; @@ -33,7 +33,7 @@ public static void deleteFile(File file){ public static boolean isFileDownloaded(String fileAddress, ILabel lblFileContent) { try { - BrowserManager.getBrowser().goTo(fileAddress); + AqualityServices.getBrowser().goTo(fileAddress); return lblFileContent.state().isDisplayed(); } catch (WebDriverException e) { Logger.getInstance().warn(e.getMessage()); @@ -42,7 +42,7 @@ public static boolean isFileDownloaded(String fileAddress, ILabel lblFileContent } public static String getTargetFilePath(String fileName) { - String downloadDirectory = BrowserManager.getBrowser().getDownloadDirectory(); + String downloadDirectory = AqualityServices.getBrowser().getDownloadDirectory(); // below is workaround for case when local FS is different from remote (e.g. local machine runs on Windows but remote runs on Linux) if(downloadDirectory.contains("/") && !downloadDirectory.endsWith("/")) { diff --git a/src/test/resources/settings.incorrect.json b/src/test/resources/settings.incorrect.json index 1f3b356..fa78a04 100644 --- a/src/test/resources/settings.incorrect.json +++ b/src/test/resources/settings.incorrect.json @@ -67,5 +67,8 @@ }, "logger": { "language": "en" + }, + "elementCache": { + "isEnabled": false } } \ No newline at end of file diff --git a/src/test/resources/settings.json b/src/test/resources/settings.json index 40d95a5..0d9e972 100644 --- a/src/test/resources/settings.json +++ b/src/test/resources/settings.json @@ -67,5 +67,8 @@ }, "logger": { "language": "en" + }, + "elementCache": { + "isEnabled": false } } \ No newline at end of file diff --git a/src/test/resources/settings.local.json b/src/test/resources/settings.local.json index 857f583..2ec9d29 100644 --- a/src/test/resources/settings.local.json +++ b/src/test/resources/settings.local.json @@ -67,5 +67,8 @@ }, "logger": { "language": "en" + }, + "elementCache": { + "isEnabled": false } } \ No newline at end of file