Skip to content

Commit e53992a

Browse files
fixed issue with findElements method for elements in the specific state (#54)
* fixed issue with findElements method for elements in the specific state updated test because of changes additionally added QuickStartExample and reference to it from README file pom updated with list of developers * removed repositories section from readme added additional waitForPageToLoad after search in QuickStart example corrected messages in dictionary to get more clean message * fixes of syntax issues updated test of findElements updated QuickStartExample updated readme * updated chromedriver version in the maven command * updated circleci docker image * added and updated azure pipelines profile * added and updated azure pipelines profile * add timer class usage to ElementActionRetrierTest * refactored download dir test * fix for element retrier test - timer is inside of each test * removed circle ci config * update testRetrierShouldWaitPollingTimeBetweenMethodsCall split assertion to get more informative message in case of failure * extend logging. rework testRetrierShouldWorkCorrectTimes test * fix logged variable * comment not failed tests * moved retrier to non-threadsafe tests * increase pageload timeout * Update azure-pipelines.yml for Azure Pipelines add ScreenResolutionUtility task * removed duplication from ActionTests. try to set FirefoxDriver to be x32 * fix ElementFactory and some tests * set parallel to false in suite file * stabilize ActionTests related to focus on last product tile * try to remove some forks settings from the pom file * try to set parallel to none for some tests * fix spaces in test
1 parent 2f8f027 commit e53992a

File tree

17 files changed

+124
-98
lines changed

17 files changed

+124
-98
lines changed

.circleci/config.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,29 @@ Browser browser = BrowserManager.getBrowser();
2828
```java
2929
browser.maximize();
3030
browser.goTo("https://wikipedia.org");
31-
browser.waitForPageToLoad()
31+
browser.waitForPageToLoad();
3232
```
3333

3434
4. Use ElementFactory class's methods to get an instance of each element.
3535
```java
36-
ITextBox txbEmail = new ElementFactory().getTextBox(By.id("email_create"), "Email");
36+
ElementFactory elementFactory = new ElementFactory();
37+
ITextBox txbSearch = elementFactory.getTextBox(By.id("searchInput"), "Search");
38+
txbSearch.submit();
39+
browser.waitForPageToLoad();
3740
```
3841

3942
5. Call element's methods to perform action with element:
4043
```java
41-
txbEmail.type("[email protected]");
44+
txbSearch.type("quality assurance");
4245
```
4346

4447
6. Quit browser at the end
4548
```
4649
browser.quit();
4750
```
4851

52+
See full example [here](./src/test/java/tests/usecases/QuickStartExample.java)
53+
4954
### Documentation
5055
To get more details please look at documentation:
5156
- [In English](./Documentation.en.md)

azure-pipelines.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ pool:
1010
vmImage: 'windows-latest'
1111

1212
steps:
13+
- task: ScreenResolutionUtility@1
14+
inputs:
15+
displaySettings: 'optimal'
1316
- task: Maven@3
1417
inputs:
1518
mavenPomFile: 'pom.xml'
@@ -19,4 +22,4 @@ steps:
1922
jdkArchitectureOption: 'x64'
2023
publishJUnitResults: true
2124
testResultsFiles: '**/surefire-reports/TEST-*.xml'
22-
goals: 'clean test'
25+
goals: 'clean test -DdriverSettings.chrome.webDriverVersion=75.0.3770.140 -Dprofile=local'

pom.xml

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.aquality-automation</groupId>
88
<artifactId>aquality-selenium</artifactId>
9-
<version>1.1</version>
9+
<version>1.1.1</version>
1010
<packaging>jar</packaging>
1111

1212
<name>Aquality Selenium</name>
@@ -45,8 +45,24 @@
4545

4646
<developers>
4747
<developer>
48-
<id>aquality-automation</id>
49-
<name>aquality-automation</name>
48+
<id>DmitryBogatko</id>
49+
<name>Dmitry Bogatko</name>
50+
</developer>
51+
<developer>
52+
<id>pavelanihimovsky</id>
53+
<name>Pavel Anihimovsky</name>
54+
</developer>
55+
<developer>
56+
<id>Nikikuzi</id>
57+
<name>Nikita Kuznetsov</name>
58+
</developer>
59+
<developer>
60+
<id>mialeska</id>
61+
<name>Alaksiej Mialeška</name>
62+
</developer>
63+
<developer>
64+
<id>sunigos</id>
65+
<name>Igor Sontsa</name>
5066
</developer>
5167
</developers>
5268

@@ -147,12 +163,10 @@
147163
<version>2.20</version>
148164
<configuration>
149165
<argLine>${surefireArgLine} -Dfile.encoding=UTF-8</argLine>
150-
<parallel>methods</parallel>
151-
<forkCount>10</forkCount>
152166
<reuseForks>false</reuseForks>
153-
<includes>
154-
<include>**/*Test*.java</include>
155-
</includes>
167+
<suiteXmlFiles>
168+
<suiteXmlFile>src/test/resources/TestSuite.xml</suiteXmlFile>
169+
</suiteXmlFiles>
156170
</configuration>
157171
</plugin>
158172
<plugin>

src/main/java/aquality/selenium/elements/ElementFactory.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import aquality.selenium.browser.BrowserManager;
55
import aquality.selenium.browser.JavaScript;
66
import aquality.selenium.configuration.Configuration;
7+
import aquality.selenium.configuration.ITimeoutConfiguration;
78
import aquality.selenium.elements.interfaces.*;
89
import aquality.selenium.localization.LocalizationManager;
910
import aquality.selenium.logger.Logger;
@@ -101,18 +102,21 @@ private <T extends IElement> List<T> findElementsCore(By locator, IElementSuppl
101102
List<T> elements = new ArrayList<>();
102103
switch (count) {
103104
case ZERO:
105+
ConditionalWait.waitFor(driver -> driver.findElements(locator).stream()
106+
.noneMatch(webElement -> state == ElementState.EXISTS_IN_ANY_STATE || webElement.isDisplayed()),
107+
String.format(LocalizationManager.getInstance().getValue("loc.elements.found.but.should.not"),
108+
locator.toString()));
104109
break;
105110
case MORE_THEN_ZERO:
106111
ConditionalWait.waitFor(driver -> !driver.findElements(locator).isEmpty(),
107-
String.format(LocalizationManager.getInstance().getValue("loc.no.elements.found.in.state"),
108-
locator.toString(),
109-
state.toString(),
110-
Configuration.getInstance().getTimeoutConfiguration().getCondition()));
112+
String.format(LocalizationManager.getInstance().getValue("loc.no.elements.found.by.locator"),
113+
locator.toString()));
111114
break;
112115
default:
113116
throw new IllegalArgumentException("No such expected value:".concat(count.toString()));
114117
}
115-
List<WebElement> webElements = getBrowser().getDriver().findElements(locator);
118+
119+
List<WebElement> webElements = ElementFinder.getInstance().findElements(locator, getTimeoutConfig().getCondition(), state);
116120
int index = 1;
117121
for (WebElement webElement : webElements) {
118122
try {
@@ -180,5 +184,9 @@ private Type convertElementClassToType(Class<? extends IElement> clazz){
180184
private Browser getBrowser(){
181185
return BrowserManager.getBrowser();
182186
}
187+
188+
private ITimeoutConfiguration getTimeoutConfig(){
189+
return Configuration.getInstance().getTimeoutConfiguration();
190+
}
183191
}
184192

src/main/resources/localization/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,6 @@
6363
"loc.waitnotexists" : "Wait until element does not exist in DOM during %1$s seconds",
6464
"loc.no.elements.found.in.state" : "no elements with locator '%1$s' found in state '%2$s' during %3$s seconds",
6565
"loc.no.elements.found.by.locator" : "No elements were found by locator '%1$s'",
66-
"loc.elements.were.found.but.not.in.state" : "Elements were found by locator '%1$s'. But %2$s"
66+
"loc.elements.were.found.but.not.in.state" : "Elements were found by locator '%1$s' but not in desired state. %2$s",
67+
"loc.elements.found.but.should.not": "No elements should be found by locator '%1$s'"
6768
}

src/main/resources/localization/ru.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,6 @@
6363
"loc.waitnotexists" : "Ожидаем исчезновения элемента из DOM в течении %1$s",
6464
"loc.no.elements.found.in.state" : "не удалось найти элементов по локатору '%1$s' в состоянии '%2$s' на протяжении %3$s секунд",
6565
"loc.no.elements.found.by.locator" : "Не удалось найти элементов по локатору '%1$s'",
66-
"loc.elements.were.found.but.not.in.state" : "Удалось найти элементы по локатору '%1$s'. Но %2$s"
66+
"loc.elements.were.found.but.not.in.state" : "Удалось найти элементы по локатору '%1$s',но они не в желаемом состоянии. %2$s",
67+
"loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s'"
6768
}

src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
11
package aquality.selenium.utils;
22

33
import aquality.selenium.configuration.Configuration;
4+
import aquality.selenium.logger.Logger;
5+
import org.apache.commons.lang3.time.StopWatch;
46
import org.openqa.selenium.InvalidArgumentException;
57
import org.openqa.selenium.InvalidElementStateException;
68
import org.openqa.selenium.StaleElementReferenceException;
79
import org.testng.annotations.DataProvider;
810
import org.testng.annotations.Test;
11+
import utils.Timer;
912

1013
import java.lang.reflect.Constructor;
1114
import java.lang.reflect.InvocationTargetException;
1215
import java.util.Date;
16+
import java.util.concurrent.TimeUnit;
1317
import java.util.concurrent.atomic.AtomicBoolean;
18+
import java.util.concurrent.atomic.AtomicInteger;
1419

15-
import static org.testng.Assert.*;
20+
import static org.testng.Assert.assertEquals;
21+
import static org.testng.Assert.assertTrue;
1622

1723
public class ElementActionRetrierTests {
1824

19-
private static final int attemptsCount = Configuration.getInstance().getRetryConfiguration().getNumber();
25+
private static final int retriesCount = Configuration.getInstance().getRetryConfiguration().getNumber();
2026
private static final long pollingInterval = Configuration.getInstance().getRetryConfiguration().getPollingInterval();
2127

28+
2229
@DataProvider
2330
private Object[][] handledExceptions() {
2431
return new Object[][] {
@@ -36,16 +43,20 @@ public void testRetrierShouldWorkOnceIfMethodSucceeded() {
3643

3744
@Test(dataProvider = "handledExceptions")
3845
public void testRetrierShouldWaitPollingTimeBetweenMethodsCall(RuntimeException handledException) {
39-
Date startTime = new Date();
46+
StopWatch stopWatch = new StopWatch();
47+
stopWatch.start();
4048
AtomicBoolean isThrowException = new AtomicBoolean(true);
4149
ElementActionRetrier.doWithRetry(() -> {
4250
if (isThrowException.get()) {
4351
isThrowException.set(false);
4452
throw handledException;
4553
}
4654
});
47-
long duration = new Date().getTime() - startTime.getTime();
48-
assertTrue(duration >= pollingInterval && duration < 2 * pollingInterval);
55+
stopWatch.stop();
56+
57+
long duration = stopWatch.getTime(TimeUnit.MILLISECONDS);
58+
assertTrue(duration >= pollingInterval, "duration should be more than polling interval. actual is " + duration + " milliseconds");
59+
assertTrue(duration <= 2 * pollingInterval, "duration should be less than doubled polling interval. actual is " + duration + " milliseconds");
4960
}
5061

5162
@Test(expectedExceptions = InvalidArgumentException.class)
@@ -57,16 +68,16 @@ public void testRetrierShouldThrowUnhandledException() {
5768

5869
@Test(dataProvider = "handledExceptions")
5970
public void testRetrierShouldWorkCorrectTimes(RuntimeException handledException) {
60-
Date startTime = new Date();
71+
AtomicInteger actualAttempts = new AtomicInteger(0);
6172
try {
6273
ElementActionRetrier.doWithRetry(() -> {
74+
Logger.getInstance().info("current attempt is " + actualAttempts.incrementAndGet());
6375
throw handledException;
6476
});
6577
} catch (RuntimeException e) {
6678
assertTrue(handledException.getClass().isInstance(e));
6779
}
68-
long duration = new Date().getTime() - startTime.getTime();
69-
assertTrue(duration >= pollingInterval * attemptsCount && duration < pollingInterval * (attemptsCount + 1));
80+
assertEquals(actualAttempts.get(), retriesCount + 1, "actual attempts count is not match to expected");
7081
}
7182

7283
@Test(expectedExceptions = IllegalAccessException.class)

src/test/java/automationpractice/forms/ProductListForm.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,23 @@ public List<ILabel> getProductContainerLabels(){
2828
return getElementFactory().findElements(By.xpath(XPATH_PRODUCT_CONTAINER), ElementType.LABEL, ElementState.DISPLAYED, ElementsCount.MORE_THEN_ZERO);
2929
}
3030

31-
public ILabel getLblFirstProduct(){
31+
private ILabel getLblFirstProduct(){
3232
return getElementFactory().getLabel(By.xpath(XPATH_PRODUCT.concat("[1]")), "First product");
3333
}
3434

3535
public ILabel getLblLastProduct(){
3636
return getElementFactory().getLabel(By.id("homefeatured"), "home featured").findChildElement(By.xpath("//li".concat("[last()]")), ILabel.class);
3737
}
3838

39-
public IButton getBtnLastProductMore(){
40-
return getLblLastProduct().findChildElement(By.xpath(".//a[contains(@class, 'lnk_view')]"), ElementType.BUTTON);
39+
public IButton getBtnLastProductMoreFocused() {
40+
getLblFirstProduct().getMouseActions().moveMouseToElement();
41+
getLblLastProduct().getMouseActions().moveMouseToElement();
42+
IButton btnLastProductMore = getLblLastProduct().findChildElement(By.xpath(".//a[contains(@class, 'lnk_view')]"), ElementType.BUTTON);
43+
if(!btnLastProductMore.state().isDisplayed()) {
44+
getLblLastProduct().getMouseActions().moveMouseFromElement();
45+
getLblLastProduct().getMouseActions().moveMouseToElement();
46+
}
47+
return btnLastProductMore;
4148
}
4249

4350
public void addToCardRandomProduct(){

src/test/java/tests/integration/ActionTests.java

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,39 +43,29 @@ public void testScrollIntoView() {
4343

4444
@Test
4545
public void testMoveMouseToElement() {
46-
ProductListForm productListForm = new ProductListForm();
47-
productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
48-
productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
49-
IButton button = productListForm.getBtnLastProductMore();
46+
IButton button = new ProductListForm().getBtnLastProductMoreFocused();
5047
Assert.assertTrue(button.getText().contains("More"), "element is not focused after moveMouseToElement()");
5148
}
5249

5350
@Test
5451
public void testMoveMouseFromElement() {
5552
ProductListForm productListForm = new ProductListForm();
56-
productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
57-
IButton button = productListForm.getBtnLastProductMore();
53+
IButton button = productListForm.getBtnLastProductMoreFocused();
5854
Assert.assertTrue(button.getText().contains("More"), "element is not focused after moveMouseToElement()");
5955
productListForm.getLblLastProduct().getMouseActions().moveMouseFromElement();
6056
Assert.assertFalse(button.state().isDisplayed(), "element is still focused after moveMouseFromElement()");
6157
}
6258

6359
@Test
6460
public void testGetElementText() {
65-
ProductListForm productListForm = new ProductListForm();
66-
productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
67-
productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
68-
IButton button = productListForm.getBtnLastProductMore();
61+
IButton button = new ProductListForm().getBtnLastProductMoreFocused();
6962
Assert.assertEquals(button.getText().trim(), button.getJsActions().getElementText().trim(),
7063
"element text got via JsActions is not match to expected");
7164
}
7265

7366
@Test
7467
public void testSetFocus() {
75-
ProductListForm productListForm = new ProductListForm();
76-
productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
77-
productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
78-
productListForm.getBtnLastProductMore().getJsActions().clickAndWait();
68+
new ProductListForm().getBtnLastProductMoreFocused().getJsActions().clickAndWait();
7969

8070
ITextBox txbQuantity = new ProductForm().getTxbQuantity();
8171
txbQuantity.getJsActions().setFocus();
@@ -87,10 +77,7 @@ public void testSetFocus() {
8777

8878
@Test
8979
public void testSetValue() {
90-
ProductListForm productListForm = new ProductListForm();
91-
productListForm.getLblFirstProduct().getMouseActions().moveMouseToElement();
92-
productListForm.getLblLastProduct().getMouseActions().moveMouseToElement();
93-
productListForm.getBtnLastProductMore().getJsActions().clickAndWait();
80+
new ProductListForm().getBtnLastProductMoreFocused().getJsActions().clickAndWait();
9481

9582
ProductForm productForm = new ProductForm();
9683
ITextBox txbQuantity = productForm.getTxbQuantity();

0 commit comments

Comments
 (0)