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

ByAll was re-implemented. #680

Merged
merged 6 commits into from
Aug 3, 2017
Merged

ByAll was re-implemented. #680

merged 6 commits into from
Aug 3, 2017

Conversation

HlebHalkouski
Copy link
Contributor

Change list

ByAll was re-implemented. Now it return the fist founded element for single search.

Types of changes

What types of changes are you proposing/introducing to Java client?
Put an x in the boxes that apply

  • No changes in production code.
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Details

This changes improve time of seaching single element for 'All Possible' strategy. Now it doesn't search all possible elements for single.
Selenium implementation was for single search: invoke findElements method and return the first element in list.

@jsf-clabot
Copy link

jsf-clabot commented Jul 28, 2017

CLA assistant check
All committers have signed the CLA.

public ByAll(By[] bys) {
super(bys);
checkNotNull(bys);
if (bys.length == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

better to use isEmpty()

private By[] bys;

private Function<SearchContext, WebElement> getSearchingFunction(By by) {
return input -> {
Copy link
Contributor

Choose a reason for hiding this comment

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

return (input) -> ... is more readable


private By[] bys;

private Function<SearchContext, WebElement> getSearchingFunction(By by) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd mark it with Nullable annotation

Copy link
Contributor

Choose a reason for hiding this comment

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

Or it would be even better to return an Optional value


@Override
public WebElement findElement(SearchContext context) {
for (By by : bys) {
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Jul 28, 2017

Choose a reason for hiding this comment

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

return bys.stream()
   .map(x -> getSearchingFunction(x).apply(context))
   .filter(Optional::isPresent)
   .findFirst()
   .orElseThrow(() -> new NoSuchElementException("Cannot locate an element using " + toString()));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mykola-mokhnach I don't think that we can use stream in this case, because it returns By type not WebElement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you know how to need to do it without double invoking searching function, show me please.

Copy link
Contributor

Choose a reason for hiding this comment

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

we can. Updated my comment above


public class ByAll extends org.openqa.selenium.support.pagefactory.ByAll {

private By[] bys;
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Jul 28, 2017

Choose a reason for hiding this comment

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

I'd keep it as List<By> internally


public class ByAll extends org.openqa.selenium.support.pagefactory.ByAll {

private List<By> bys;
Copy link
Contributor

Choose a reason for hiding this comment

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

can be final

private Function<SearchContext, Optional<WebElement>> getSearchingFunction(By by) {
return input -> {
try {
return input.findElement(by);
Copy link
Contributor

Choose a reason for hiding this comment

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

return Optional.of(input.findElement(by))

.filter(Optional::isPresent)
.findFirst()
.orElseThrow(() -> new NoSuchElementException("Cannot locate an element using " + toString()))
.orElse(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

why this is needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is double Optional : Optional<Optional<WebElement>. First orElseThrow for filter, the second orElse for searching function. I can use get instead orElse, because we already check Optional::isPresent, but there is warning here: "Optional.get()' without 'isPresent()' check"

Copy link
Contributor

Choose a reason for hiding this comment

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

This would be easier to read then

bys.stream()
                .map(by -> getSearchingFunction(by).apply(context))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Cannot locate an element using " + toString()));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need a vacation

Copy link
Contributor

Choose a reason for hiding this comment

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

functional programming makes fun :)

checkNotNull(bys);

this.bys = Arrays.asList(bys);
if (this.bys.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@mykola-mokhnach
Copy link
Contributor

BTW, do we have any functional or unit test, which covers this method?

return bys.stream()
.map(by -> getSearchingFunction(by).apply(context))
.filter(Optional::isPresent)
.findFirst().map(Optional::get)
Copy link
Contributor

Choose a reason for hiding this comment

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

mapping should be done before findFirst

@TikhomirovSergey
Copy link
Contributor

@mykola-mokhnach So can we merge it or do you have some concerns/remarks?

@mykola-mokhnach
Copy link
Contributor

@TikhomirovSergey There was only one minor comment about checkArgument usage. Everything else looks good.

@TikhomirovSergey
Copy link
Contributor

@HlebHalkouski @mykola-mokhnach I will merge it soon.

@HlebHalkouski
Copy link
Contributor Author

@TikhomirovSergey ok, Thank you!

@TikhomirovSergey TikhomirovSergey mentioned this pull request Aug 3, 2017
@TikhomirovSergey TikhomirovSergey merged commit 3917b52 into appium:master Aug 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants