-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added ReplaceText modifier and Click and Hide modifiers allows to use css selectors as parameters #41
Conversation
Update Hide Modifier with find elements by css selector #15
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please also update click
and hide
tests so that css
selector is checked there?
Great stuff 👍
if (StringUtils.isNumeric(timeoutString)) { | ||
timeoutInSeconds = TimeUnit.SECONDS.convert(Long.valueOf(timeoutString), TimeUnit.MILLISECONDS); | ||
if (timeoutInSeconds < 0) { | ||
throw new ParametersException("'timeout' parameter value on Click Modifier should be greater or equal zero."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change this error message - it looks that WebElementsLocatorParams
are used not only in Click Modifier
.
Maybe it would be good idea to check 0 < timeoutInSeconds <= 15
in a single condition and serve common validation message: 'Timeout' parameter value should be in range 0 - 15 seconds
or sth. like that.
|
||
public CollectorStepResult hideElement(WebDriver driver, String xpath) throws ProcessingException { | ||
public CollectorStepResult hideElement(By locator) throws ProcessingException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks that hide does not support timeout
value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is now
value = StringUtils.defaultIfBlank(params.get(VALUE_PARAM), ""); | ||
} | ||
|
||
public CollectorStepResult replaceText() throws ProcessingException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No support for timeout
- should it be here? Maybe it is unnecessary in WebElementsLocatorParams
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's now added (including documentation)
|
||
import java.util.Map; | ||
|
||
import static org.mockito.Mockito.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't import static with *
.
@@ -11,7 +11,8 @@ Module name: **click** | |||
##### Parameters | |||
| Parameter | Default value | Description | Mandatory | | |||
| --------- | ------------- | ----------- | --------- | | |||
| `xpath` | | xpath of the element to be clicked | yes | | |||
| `xpath` | | xpath of the element to be clicked | yes | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mention that only one selector may be used in each click
modifier entry (maybe it is wroth to mention the obvious, that there may be some selectors with xpath
and some with css
in the same test).
@@ -0,0 +1,88 @@ | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be grateful for any suggestion for better place for this class
(package/name)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is a very good place for this class.
|
||
protected long getTimeoutInSeconds() { | ||
return timeoutInSeconds; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blank line
xpath = params.get(XPATH_PARAM); | ||
css = params.get(CSS_PARAM); | ||
|
||
if (StringUtils.isNotBlank(xpath) == StringUtils.isNotBlank(css)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this condition ok? what about situation when both, xpath and css are set? logical OR in the exception message means that both can be set. Either fix the condition or fix the exception message
if (timeoutInSeconds < 0) { | ||
throw new ParametersException("'timeout' parameter value should be greater or equal zero."); | ||
} else if (TIMEOUT_SECONDS_MAX_VALUE < timeoutInSeconds) { | ||
throw new ParametersException("'timeout' parameter value can't be greater than 15 seconds."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace the number from message by the constant TIMEOUT_SECONDS_MAX_VALUE
} | ||
|
||
protected String getSelectorType() { | ||
return (xpath != null) ? XPATH_PARAM : CSS_PARAM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove brackets
By elementLocator = getLocator(); | ||
waitForElementToBePresent(webDriver, elementLocator); | ||
|
||
List<WebElement> webElements = webDriver.findElements(elementLocator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lines 81-84 can be moved to the parent class as a method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could separate finding an element and updating text into two separate methods with separate try-catch blocks? (nice to have)
private static final Logger LOG = LoggerFactory.getLogger(ReplaceTextModifier.class); | ||
|
||
private static final String ATTRIBUTE_PARAM = "attributeName"; | ||
private static final String VALUE_PARAM = "value"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, you missed the gap
protected void setElementParams(Map<String, String> params) throws ParametersException { | ||
xpath = params.get(XPATH_PARAM); | ||
css = params.get(CSS_PARAM); | ||
if (StringUtils.isBlank(xpath) == StringUtils.isBlank(css)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if both parameters are provided, could we have better exception message? (should have)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo "Either" should be sufficient in this case
wait.until(ExpectedConditions.presenceOfElementLocated(elementLocator)); | ||
} | ||
|
||
private void setTimeOutParam(String timeoutString) throws ParametersException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about renaming this method so that only simple setters has the name using set... (nice to have)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initializeTimeOutParam
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @subiron for your work!
This is nice piece of code. I have added some comments though.
} | ||
|
||
protected By getLocator() { | ||
return xpath != null ? By.xpath(xpath) : By.cssSelector(css); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may have only one field in thi class By by
and initialize it in constructor.
Then the getLocator
method would be a simple getter (the name suggests that). (nice to have)
if (elementToClick.isDisplayed()) { | ||
elementToClick.click(); | ||
result = CollectorStepResult.newModifierResult(); | ||
} else { | ||
final String message = String.format("Element defined by xpath: '%s' is not yet visible! {}", xpath); | ||
final String message = String.format("Element defined by %s: '%s' is not yet visible!", getSelectorType(), getSelectorValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe By
class has a nice toString()
method and we could use it instead of saving selector type in WebElementsLocatorParams
class? (nice to have)
@Override | ||
public CollectorStepResult collect() throws ProcessingException { | ||
CollectorStepResult result; | ||
try { | ||
WebElement elementToClick = getElementByXpath(webDriver, xpath); | ||
By elementLocator = getLocator(); | ||
waitForElementToBePresent(webDriver, elementLocator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should rather wait for element to be clickable instead of present / visible. (must have)
import org.openqa.selenium.NoSuchElementException; | ||
import org.openqa.selenium.WebDriver; | ||
import org.openqa.selenium.WebElement; | ||
import org.openqa.selenium.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably don't want to use asterisk imports.. do we? (should have)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed,
but I'm not sure if it's better in any way,
why we're fallow this rule?
} | ||
result = CollectorStepResult.newModifierResult(); | ||
} catch (NoSuchElementException e) { | ||
final String message = String.format("Error while hiding element '%s'. %s", xpath, e.getMessage()); | ||
} catch (WebDriverException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could have two methods: one for finding element and the other for hiding it.
This way we could have two separate try-catch block.
(nice to have)
|
||
@Test(expected = ParametersException.class) | ||
public void setParameters_CssAndXpathAreNotPassed_ValidationPassedUnsuccessfuly() throws ParametersException { | ||
when(properties.getUrl()).thenReturn(URL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this properties
mock is ever used. If this is the case it shold be removed.
Then test methods from line 96 and 101 are the same? (must have)
|
||
@Test(expected = ParametersException.class) | ||
public void setParameters_CssAndXpathAreNotPassed_ExceptionIsThrown() throws ParametersException { | ||
when(properties.getUrl()).thenReturn(URL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this properties
mock? If not please remove it. If yes, please make it more clear what is the purpose of this mock. (must have).
@@ -79,9 +83,12 @@ The configuration above will trigger three screens collections (desktop, tablet | |||
<collect> | |||
<open/> | |||
<sleep duration="1000"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for those changes! They are not obvious and it is very good that we have them in docs!
This configuration looks a little bit redundant, but I believe this is what is required, isn't it?
👍
@@ -1916,7 +1918,7 @@ No parameters. | |||
|
|||
| ! Important information | | |||
|:----------------------- | | |||
| Timeout for waiting is 10000 milliseconds.<br/><br/> Page is checked every 1000 miliseconds. | | |||
| Timeout for waiting is 10000 milliseconds.<br/><br/> Page is checked every 1000 milliseconds. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra ! :)
<% | ||
Long millis = System.currentTimeMillis(); | ||
%> | ||
<p id="demo1">Replace me by Xpath 1: <%=millis%></p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this very much! Nice one! 👍
# Conflicts: # core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/w3chtml5/W3cHtml5ComparatorJob.java
-Click and Hide modifiers allows to use css selectors as parameters (for now, only xpath was an option)
-Added ReplaceText modifier and it's tests
I hereby agree to the terms of the AET Contributor License Agreement.