Skip to content
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

Merged
merged 15 commits into from
Jan 20, 2017

Conversation

subiron
Copy link
Contributor

@subiron subiron commented Jan 3, 2017

-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.

Copy link
Contributor

@malaskowski malaskowski left a 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.");
Copy link
Contributor

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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?

Copy link
Contributor Author

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.*;
Copy link
Contributor

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 |
Copy link
Contributor

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 @@
/**
Copy link
Contributor Author

@subiron subiron Jan 4, 2017

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)

Copy link
Contributor

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;

Copy link
Contributor

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)) {
Copy link
Contributor

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.");
Copy link
Contributor

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;
Copy link
Contributor

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);
Copy link
Contributor

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

Copy link
Contributor

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";
Copy link
Contributor

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)) {
Copy link
Contributor

@wiiitek wiiitek Jan 16, 2017

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)

Copy link
Contributor Author

@subiron subiron Jan 18, 2017

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 {
Copy link
Contributor

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)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any suggestion?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initializeTimeOutParam?

Copy link
Contributor

@wiiitek wiiitek left a 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);
Copy link
Contributor

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());
Copy link
Contributor

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);
Copy link
Contributor

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.*;
Copy link
Contributor

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)

Copy link
Contributor Author

@subiron subiron Jan 19, 2017

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) {
Copy link
Contributor

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);
Copy link
Contributor

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);
Copy link
Contributor

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"/>
Copy link
Contributor

@wiiitek wiiitek Jan 16, 2017

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. |
Copy link
Contributor

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>
Copy link
Contributor

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! 👍

@subiron subiron merged commit cc3512a into master Jan 20, 2017
@subiron subiron deleted the feature/modifiers_enhancements branch January 23, 2017 07:31
@subiron subiron changed the title Feature/modifiers enhancements Added ReplaceText modifier and Modifiers enhancements Feb 24, 2017
@subiron subiron changed the title Added ReplaceText modifier and Modifiers enhancements Added ReplaceText modifier and Click and Hide modifiers allows to use css selectors as parameters Feb 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants