diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index c5fded7..0000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-version: 2
-jobs:
- build:
- docker:
- - image: circleci/openjdk:8-jdk-stretch-node-browsers
-
- working_directory: ~/repo
-
- environment:
- # Customize the JVM maximum heap limit
- MAVEN_OPTS: -Xmx3200m
-
- steps:
- - checkout
-
- # Download and cache dependencies
- - restore_cache:
- keys:
- - v1-dependencies-{{ checksum "pom.xml" }}
- # fallback to using the latest cache if no exact match is found
- - v1-dependencies-
-
- - run: mvn dependency:go-offline
-
- - save_cache:
- paths:
- - ~/.m2
- key: v1-dependencies-{{ checksum "pom.xml" }}
-
- - run: mvn clean test -Dprofile=local
\ No newline at end of file
diff --git a/README.md b/README.md
index eea226c..29bb5a0 100644
--- a/README.md
+++ b/README.md
@@ -12,17 +12,6 @@ We use interfaces where is possible, so you can implement your own version of ta
1. To start work with this package, simply add the dependency to your pom.xml:
```
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
- ossrh
- https://repo1.maven.org/maven2/
-
-
-
com.github.aquality-automation
aquality-selenium
@@ -39,17 +28,20 @@ Browser browser = BrowserManager.getBrowser();
```java
browser.maximize();
browser.goTo("https://wikipedia.org");
-browser.waitForPageToLoad()
+browser.waitForPageToLoad();
```
4. Use ElementFactory class's methods to get an instance of each element.
```java
-ITextBox txbEmail = new ElementFactory().getTextBox(By.id("email_create"), "Email");
+ElementFactory elementFactory = new ElementFactory();
+ITextBox txbSearch = elementFactory.getTextBox(By.id("searchInput"), "Search");
+txbSearch.submit();
+browser.waitForPageToLoad();
```
5. Call element's methods to perform action with element:
```java
-txbEmail.type("email@domain.com");
+txbSearch.type("quality assurance");
```
6. Quit browser at the end
@@ -57,6 +49,8 @@ txbEmail.type("email@domain.com");
browser.quit();
```
+See full example [here](./src/test/java/tests/usecases/QuickStartExample.java)
+
### Documentation
To get more details please look at documentation:
- [In English](./Documentation.en.md)
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 23efa78..dbfb903 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -10,6 +10,9 @@ pool:
vmImage: 'windows-latest'
steps:
+- task: ScreenResolutionUtility@1
+ inputs:
+ displaySettings: 'optimal'
- task: Maven@3
inputs:
mavenPomFile: 'pom.xml'
@@ -19,4 +22,4 @@ steps:
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/surefire-reports/TEST-*.xml'
- goals: 'clean test'
+ goals: 'clean test -DdriverSettings.chrome.webDriverVersion=75.0.3770.140 -Dprofile=local'
diff --git a/pom.xml b/pom.xml
index edef694..b7ae786 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.github.aquality-automation
aquality-selenium
- 1.1
+ 1.1.1
jar
Aquality Selenium
@@ -45,8 +45,24 @@
- aquality-automation
- aquality-automation
+ DmitryBogatko
+ Dmitry Bogatko
+
+
+ pavelanihimovsky
+ Pavel Anihimovsky
+
+
+ Nikikuzi
+ Nikita Kuznetsov
+
+
+ mialeska
+ Alaksiej Mialeška
+
+
+ sunigos
+ Igor Sontsa
@@ -147,12 +163,10 @@
2.20
${surefireArgLine} -Dfile.encoding=UTF-8
- methods
- 10
false
-
- **/*Test*.java
-
+
+ src/test/resources/TestSuite.xml
+
diff --git a/src/main/java/aquality/selenium/elements/ElementFactory.java b/src/main/java/aquality/selenium/elements/ElementFactory.java
index 000e4bf..776ce17 100644
--- a/src/main/java/aquality/selenium/elements/ElementFactory.java
+++ b/src/main/java/aquality/selenium/elements/ElementFactory.java
@@ -4,6 +4,7 @@
import aquality.selenium.browser.BrowserManager;
import aquality.selenium.browser.JavaScript;
import aquality.selenium.configuration.Configuration;
+import aquality.selenium.configuration.ITimeoutConfiguration;
import aquality.selenium.elements.interfaces.*;
import aquality.selenium.localization.LocalizationManager;
import aquality.selenium.logger.Logger;
@@ -101,18 +102,21 @@ private List findElementsCore(By locator, IElementSuppl
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.in.state"),
- locator.toString(),
- state.toString(),
- Configuration.getInstance().getTimeoutConfiguration().getCondition()));
+ 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 = getBrowser().getDriver().findElements(locator);
+
+ List webElements = ElementFinder.getInstance().findElements(locator, getTimeoutConfig().getCondition(), state);
int index = 1;
for (WebElement webElement : webElements) {
try {
@@ -180,5 +184,9 @@ private Type convertElementClassToType(Class extends IElement> clazz){
private Browser getBrowser(){
return BrowserManager.getBrowser();
}
+
+ private ITimeoutConfiguration getTimeoutConfig(){
+ return Configuration.getInstance().getTimeoutConfiguration();
+ }
}
diff --git a/src/main/resources/localization/en.json b/src/main/resources/localization/en.json
index 85bc2df..99c4eb1 100644
--- a/src/main/resources/localization/en.json
+++ b/src/main/resources/localization/en.json
@@ -63,5 +63,6 @@
"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.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 %2$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'"
}
\ No newline at end of file
diff --git a/src/main/resources/localization/ru.json b/src/main/resources/localization/ru.json
index 2cedf91..20f07e9 100644
--- a/src/main/resources/localization/ru.json
+++ b/src/main/resources/localization/ru.json
@@ -63,5 +63,6 @@
"loc.waitnotexists" : "Ожидаем исчезновения элемента из DOM в течении %1$s",
"loc.no.elements.found.in.state" : "не удалось найти элементов по локатору '%1$s' в состоянии '%2$s' на протяжении %3$s секунд",
"loc.no.elements.found.by.locator" : "Не удалось найти элементов по локатору '%1$s'",
- "loc.elements.were.found.but.not.in.state" : "Удалось найти элементы по локатору '%1$s'. Но %2$s"
+ "loc.elements.were.found.but.not.in.state" : "Удалось найти элементы по локатору '%1$s',но они не в желаемом состоянии. %2$s",
+ "loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s'"
}
\ No newline at end of file
diff --git a/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java b/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java
index bf25f4f..1a79e3d 100644
--- a/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java
+++ b/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java
@@ -1,24 +1,31 @@
package aquality.selenium.utils;
import aquality.selenium.configuration.Configuration;
+import aquality.selenium.logger.Logger;
+import org.apache.commons.lang3.time.StopWatch;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.StaleElementReferenceException;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import utils.Timer;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
-import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
public class ElementActionRetrierTests {
- private static final int attemptsCount = Configuration.getInstance().getRetryConfiguration().getNumber();
+ private static final int retriesCount = Configuration.getInstance().getRetryConfiguration().getNumber();
private static final long pollingInterval = Configuration.getInstance().getRetryConfiguration().getPollingInterval();
+
@DataProvider
private Object[][] handledExceptions() {
return new Object[][] {
@@ -36,7 +43,8 @@ public void testRetrierShouldWorkOnceIfMethodSucceeded() {
@Test(dataProvider = "handledExceptions")
public void testRetrierShouldWaitPollingTimeBetweenMethodsCall(RuntimeException handledException) {
- Date startTime = new Date();
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
AtomicBoolean isThrowException = new AtomicBoolean(true);
ElementActionRetrier.doWithRetry(() -> {
if (isThrowException.get()) {
@@ -44,8 +52,11 @@ public void testRetrierShouldWaitPollingTimeBetweenMethodsCall(RuntimeException
throw handledException;
}
});
- long duration = new Date().getTime() - startTime.getTime();
- assertTrue(duration >= pollingInterval && duration < 2 * pollingInterval);
+ stopWatch.stop();
+
+ long duration = stopWatch.getTime(TimeUnit.MILLISECONDS);
+ assertTrue(duration >= pollingInterval, "duration should be more than polling interval. actual is " + duration + " milliseconds");
+ assertTrue(duration <= 2 * pollingInterval, "duration should be less than doubled polling interval. actual is " + duration + " milliseconds");
}
@Test(expectedExceptions = InvalidArgumentException.class)
@@ -57,16 +68,16 @@ public void testRetrierShouldThrowUnhandledException() {
@Test(dataProvider = "handledExceptions")
public void testRetrierShouldWorkCorrectTimes(RuntimeException handledException) {
- Date startTime = new Date();
+ AtomicInteger actualAttempts = new AtomicInteger(0);
try {
ElementActionRetrier.doWithRetry(() -> {
+ Logger.getInstance().info("current attempt is " + actualAttempts.incrementAndGet());
throw handledException;
});
} catch (RuntimeException e) {
assertTrue(handledException.getClass().isInstance(e));
}
- long duration = new Date().getTime() - startTime.getTime();
- assertTrue(duration >= pollingInterval * attemptsCount && duration < pollingInterval * (attemptsCount + 1));
+ assertEquals(actualAttempts.get(), retriesCount + 1, "actual attempts count is not match to expected");
}
@Test(expectedExceptions = IllegalAccessException.class)
diff --git a/src/test/java/automationpractice/forms/ProductListForm.java b/src/test/java/automationpractice/forms/ProductListForm.java
index 8d3729c..1b8bc68 100644
--- a/src/test/java/automationpractice/forms/ProductListForm.java
+++ b/src/test/java/automationpractice/forms/ProductListForm.java
@@ -28,7 +28,7 @@ public List getProductContainerLabels(){
return getElementFactory().findElements(By.xpath(XPATH_PRODUCT_CONTAINER), ElementType.LABEL, ElementState.DISPLAYED, ElementsCount.MORE_THEN_ZERO);
}
- public ILabel getLblFirstProduct(){
+ private ILabel getLblFirstProduct(){
return getElementFactory().getLabel(By.xpath(XPATH_PRODUCT.concat("[1]")), "First product");
}
@@ -36,8 +36,15 @@ public ILabel getLblLastProduct(){
return getElementFactory().getLabel(By.id("homefeatured"), "home featured").findChildElement(By.xpath("//li".concat("[last()]")), ILabel.class);
}
- public IButton getBtnLastProductMore(){
- return getLblLastProduct().findChildElement(By.xpath(".//a[contains(@class, 'lnk_view')]"), ElementType.BUTTON);
+ public IButton getBtnLastProductMoreFocused() {
+ getLblFirstProduct().getMouseActions().moveMouseToElement();
+ getLblLastProduct().getMouseActions().moveMouseToElement();
+ IButton btnLastProductMore = getLblLastProduct().findChildElement(By.xpath(".//a[contains(@class, 'lnk_view')]"), ElementType.BUTTON);
+ if(!btnLastProductMore.state().isDisplayed()) {
+ getLblLastProduct().getMouseActions().moveMouseFromElement();
+ getLblLastProduct().getMouseActions().moveMouseToElement();
+ }
+ return btnLastProductMore;
}
public void addToCardRandomProduct(){
diff --git a/src/test/java/tests/integration/ActionTests.java b/src/test/java/tests/integration/ActionTests.java
index d825db3..28a9ece 100644
--- a/src/test/java/tests/integration/ActionTests.java
+++ b/src/test/java/tests/integration/ActionTests.java
@@ -43,18 +43,14 @@ public void testScrollIntoView() {
@Test
public void testMoveMouseToElement() {
- ProductListForm productListForm = new ProductListForm();
- productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
- productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
- IButton button = productListForm.getBtnLastProductMore();
+ IButton button = new ProductListForm().getBtnLastProductMoreFocused();
Assert.assertTrue(button.getText().contains("More"), "element is not focused after moveMouseToElement()");
}
@Test
public void testMoveMouseFromElement() {
ProductListForm productListForm = new ProductListForm();
- productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
- IButton button = productListForm.getBtnLastProductMore();
+ IButton button = productListForm.getBtnLastProductMoreFocused();
Assert.assertTrue(button.getText().contains("More"), "element is not focused after moveMouseToElement()");
productListForm.getLblLastProduct().getMouseActions().moveMouseFromElement();
Assert.assertFalse(button.state().isDisplayed(), "element is still focused after moveMouseFromElement()");
@@ -62,20 +58,14 @@ public void testMoveMouseFromElement() {
@Test
public void testGetElementText() {
- ProductListForm productListForm = new ProductListForm();
- productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
- productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
- IButton button = productListForm.getBtnLastProductMore();
+ IButton button = new ProductListForm().getBtnLastProductMoreFocused();
Assert.assertEquals(button.getText().trim(), button.getJsActions().getElementText().trim(),
"element text got via JsActions is not match to expected");
}
@Test
public void testSetFocus() {
- ProductListForm productListForm = new ProductListForm();
- productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
- productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
- productListForm.getBtnLastProductMore().getJsActions().clickAndWait();
+ new ProductListForm().getBtnLastProductMoreFocused().getJsActions().clickAndWait();
ITextBox txbQuantity = new ProductForm().getTxbQuantity();
txbQuantity.getJsActions().setFocus();
@@ -87,10 +77,7 @@ public void testSetFocus() {
@Test
public void testSetValue() {
- ProductListForm productListForm = new ProductListForm();
- productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
- productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
- productListForm.getBtnLastProductMore().getJsActions().clickAndWait();
+ new ProductListForm().getBtnLastProductMoreFocused().getJsActions().clickAndWait();
ProductForm productForm = new ProductForm();
ITextBox txbQuantity = productForm.getTxbQuantity();
diff --git a/src/test/java/tests/integration/BrowserTests.java b/src/test/java/tests/integration/BrowserTests.java
index e21609b..fe385a0 100644
--- a/src/test/java/tests/integration/BrowserTests.java
+++ b/src/test/java/tests/integration/BrowserTests.java
@@ -16,8 +16,6 @@
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.util.ArrayList;
-import java.util.List;
import static automationpractice.Constants.URL_AUTOMATIONPRACTICE;
import static utils.FileUtil.getResourceFileByName;
@@ -204,15 +202,7 @@ public void testShouldBePossibleToSetImplicitWait(){
@Test
public void testShouldBePossibleToGetDownloadDir(){
- List listOfDownloadDirs = new ArrayList<>();
- listOfDownloadDirs.add("//home//selenium//downloads");
- listOfDownloadDirs.add("/Users/username/Downloads");
- listOfDownloadDirs.add("target//downloads");
- listOfDownloadDirs.add("/home/circleci/repo/target/downloads");
-
- boolean isDirFound = listOfDownloadDirs.stream()
- .anyMatch(dir -> getBrowser().getDownloadDirectory().toLowerCase().contains(dir.toLowerCase()));
- Assert.assertTrue(isDirFound, "Browser download directory is not correct " + getBrowser().getDownloadDirectory());
+ Assert.assertFalse(getBrowser().getDownloadDirectory().isEmpty(), "Browser download directory should not be empty " + getBrowser().getDownloadDirectory());
}
private JsonFile getSettings() {
diff --git a/src/test/java/tests/integration/ElementStateTests.java b/src/test/java/tests/integration/ElementStateTests.java
index fe3f744..8952120 100644
--- a/src/test/java/tests/integration/ElementStateTests.java
+++ b/src/test/java/tests/integration/ElementStateTests.java
@@ -16,7 +16,7 @@
public class ElementStateTests extends BaseTest {
- private final double operationTime = 2;
+ private final double operationTime = 5;
private final long customWaitTime = 2L;
private final ElementFactory elementFactory = new ElementFactory();
private final ILabel lblNotExists = elementFactory.getLabel(By.xpath("//div[@class='not exist element']"), "not exist element");
diff --git a/src/test/java/tests/integration/HiddenElementsTests.java b/src/test/java/tests/integration/HiddenElementsTests.java
index 8dda321..00fe5a3 100644
--- a/src/test/java/tests/integration/HiddenElementsTests.java
+++ b/src/test/java/tests/integration/HiddenElementsTests.java
@@ -35,9 +35,8 @@ public void testHiddenElementsExist() {
}
@Test
- public void testNotHiddenElementsNotDisplayed() {
- List listElements = new SliderForm().getListElements(ElementState.DISPLAYED, ElementsCount.MORE_THEN_ZERO);
- Assert.assertFalse(listElements.isEmpty());
- Assert.assertFalse(listElements.stream().anyMatch(label -> label.state().waitForDisplayed(1L)));
+ public void testFindDisplayedElementsShouldReturnNoElementsIfTheyAreNotDisplayed() {
+ List listElements = new SliderForm().getListElements(ElementState.DISPLAYED, ElementsCount.ZERO);
+ Assert.assertTrue(listElements.isEmpty());
}
}
diff --git a/src/test/java/tests/usecases/BrowserFactoryTests.java b/src/test/java/tests/usecases/BrowserFactoryTests.java
index 849dd47..3735f42 100644
--- a/src/test/java/tests/usecases/BrowserFactoryTests.java
+++ b/src/test/java/tests/usecases/BrowserFactoryTests.java
@@ -37,7 +37,8 @@ public class BrowserFactoryTests {
private final JsonFile jsonProfile;
public BrowserFactoryTests() {
- this.jsonProfile = new JsonFile("settings.json");
+ String settingsProfile = System.getProperty("profile") == null ? "settings.json" : "settings." + System.getProperty("profile") + ".json";
+ this.jsonProfile = new JsonFile(settingsProfile);
}
@Test
diff --git a/src/test/java/tests/usecases/QuickStartExample.java b/src/test/java/tests/usecases/QuickStartExample.java
new file mode 100644
index 0000000..55b8319
--- /dev/null
+++ b/src/test/java/tests/usecases/QuickStartExample.java
@@ -0,0 +1,28 @@
+package tests.usecases;
+
+import aquality.selenium.browser.Browser;
+import aquality.selenium.browser.BrowserManager;
+import aquality.selenium.elements.ElementFactory;
+import aquality.selenium.elements.interfaces.ITextBox;
+import org.openqa.selenium.By;
+import org.testng.annotations.Test;
+
+public class QuickStartExample {
+
+ @Test
+ public void test(){
+ Browser browser = BrowserManager.getBrowser();
+
+ browser.maximize();
+ browser.goTo("https://wikipedia.org");
+ browser.waitForPageToLoad();
+
+ ElementFactory elementFactory = new ElementFactory();
+ ITextBox txbSearch = elementFactory.getTextBox(By.id("searchInput"), "Search");
+ txbSearch.type("quality assurance");
+ txbSearch.submit();
+ browser.waitForPageToLoad();
+
+ browser.quit();
+ }
+}
diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml
index 1704580..213e913 100644
--- a/src/test/resources/TestSuite.xml
+++ b/src/test/resources/TestSuite.xml
@@ -10,7 +10,6 @@
-
@@ -23,11 +22,12 @@
-
+
+
\ No newline at end of file
diff --git a/src/test/resources/settings.local.json b/src/test/resources/settings.local.json
index ed81881..857f583 100644
--- a/src/test/resources/settings.local.json
+++ b/src/test/resources/settings.local.json
@@ -22,6 +22,7 @@
},
"firefox": {
"webDriverVersion": "latest",
+ "systemArchitecture": "X32",
"capabilities": {
"enableVNC": true
},
@@ -56,7 +57,7 @@
"timeoutImplicit" : 0,
"timeoutCondition" : 30,
"timeoutScript" : 10,
- "timeoutPageLoad" : 15,
+ "timeoutPageLoad" : 30,
"timeoutPollingInterval": 300,
"timeoutCommand": 120
},