Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
223076e
fixed issue with findElements method for elements in the specific state
Aug 26, 2019
dee9b14
removed repositories section from readme
Aug 27, 2019
85c4716
fixes of syntax issues
Aug 27, 2019
6f17aab
updated chromedriver version in the maven command
Aug 29, 2019
91d1eaa
updated circleci docker image
Aug 29, 2019
83d3b8c
Merge branch 'master' of https://github.com/aquality-automation/aqual…
Aug 29, 2019
3dda666
added and updated azure pipelines profile
Aug 29, 2019
3b4b839
added and updated azure pipelines profile
Aug 29, 2019
a6cad93
add timer class usage to ElementActionRetrierTest
Aug 29, 2019
17de5d8
refactored download dir test
Aug 29, 2019
74c2781
fix for element retrier test - timer is inside of each test
Aug 29, 2019
925e0b2
removed circle ci config
Aug 29, 2019
d32b98d
update testRetrierShouldWaitPollingTimeBetweenMethodsCall
mialeska Sep 3, 2019
e251978
extend logging. rework testRetrierShouldWorkCorrectTimes test
mialeska Sep 3, 2019
45febc6
fix logged variable
mialeska Sep 3, 2019
c1fbb64
comment not failed tests
mialeska Sep 3, 2019
3ff26a7
moved retrier to non-threadsafe tests
mialeska Sep 3, 2019
cdaf457
increase pageload timeout
mialeska Sep 3, 2019
c6c4f0a
Update azure-pipelines.yml for Azure Pipelines
mialeska Sep 3, 2019
d98c9b7
removed duplication from ActionTests.
mialeska Sep 3, 2019
6ffef0b
Merge remote-tracking branch 'origin/findelements-should-return-only-…
mialeska Sep 3, 2019
5eeb09d
fix ElementFactory and some tests
mialeska Sep 3, 2019
4de5905
set parallel to false in suite file
mialeska Sep 3, 2019
cf22deb
stabilize ActionTests related to focus on last product tile
mialeska Sep 3, 2019
5eee0a2
try to remove some forks settings from the pom file
mialeska Sep 3, 2019
50359a1
try to set parallel to none for some tests
mialeska Sep 3, 2019
faa8cb9
fix spaces in test
mialeska Sep 3, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions .circleci/config.yml

This file was deleted.

22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
```
<repositories>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<repository>
<id>ossrh</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>

<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium</artifactId>
Expand All @@ -39,24 +28,29 @@ 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
```
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)
Expand Down
5 changes: 4 additions & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ pool:
vmImage: 'windows-latest'

steps:
- task: ScreenResolutionUtility@1
inputs:
displaySettings: 'optimal'
- task: Maven@3
inputs:
mavenPomFile: 'pom.xml'
Expand All @@ -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'
30 changes: 22 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium</artifactId>
<version>1.1</version>
<version>1.1.1</version>
<packaging>jar</packaging>

<name>Aquality Selenium</name>
Expand Down Expand Up @@ -45,8 +45,24 @@

<developers>
<developer>
<id>aquality-automation</id>
<name>aquality-automation</name>
<id>DmitryBogatko</id>
<name>Dmitry Bogatko</name>
</developer>
<developer>
<id>pavelanihimovsky</id>
<name>Pavel Anihimovsky</name>
</developer>
<developer>
<id>Nikikuzi</id>
<name>Nikita Kuznetsov</name>
</developer>
<developer>
<id>mialeska</id>
<name>Alaksiej Mialeška</name>
</developer>
<developer>
<id>sunigos</id>
<name>Igor Sontsa</name>
</developer>
</developers>

Expand Down Expand Up @@ -147,12 +163,10 @@
<version>2.20</version>
<configuration>
<argLine>${surefireArgLine} -Dfile.encoding=UTF-8</argLine>
<parallel>methods</parallel>
<forkCount>10</forkCount>
<reuseForks>false</reuseForks>
<includes>
<include>**/*Test*.java</include>
</includes>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/TestSuite.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
Expand Down
18 changes: 13 additions & 5 deletions src/main/java/aquality/selenium/elements/ElementFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -101,18 +102,21 @@ private <T extends IElement> List<T> findElementsCore(By locator, IElementSuppl
List<T> 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<WebElement> webElements = getBrowser().getDriver().findElements(locator);

List<WebElement> webElements = ElementFinder.getInstance().findElements(locator, getTimeoutConfig().getCondition(), state);
int index = 1;
for (WebElement webElement : webElements) {
try {
Expand Down Expand Up @@ -180,5 +184,9 @@ private Type convertElementClassToType(Class<? extends IElement> clazz){
private Browser getBrowser(){
return BrowserManager.getBrowser();
}

private ITimeoutConfiguration getTimeoutConfig(){
return Configuration.getInstance().getTimeoutConfiguration();
}
}

3 changes: 2 additions & 1 deletion src/main/resources/localization/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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'"
}
3 changes: 2 additions & 1 deletion src/main/resources/localization/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -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'"
}
Original file line number Diff line number Diff line change
@@ -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[][] {
Expand All @@ -36,16 +43,20 @@ 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()) {
isThrowException.set(false);
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)
Expand All @@ -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)
Expand Down
13 changes: 10 additions & 3 deletions src/test/java/automationpractice/forms/ProductListForm.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,23 @@ public List<ILabel> 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");
}

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(){
Expand Down
23 changes: 5 additions & 18 deletions src/test/java/tests/integration/ActionTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,39 +43,29 @@ 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()");
}

@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();
Expand All @@ -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();
Expand Down
Loading