Skip to content

Commit

Permalink
feat: Add support of multiple image occurrences (#1445)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach committed Feb 19, 2021
1 parent ff10d91 commit d5ec15a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

public class OccurrenceMatchingOptions extends BaseComparisonOptions<OccurrenceMatchingOptions> {
private Double threshold;
private Boolean multiple;
private Integer matchNeighbourThreshold;

/**
* At what normalized threshold to reject an occurrence.
Expand All @@ -36,11 +38,38 @@ public OccurrenceMatchingOptions withThreshold(double threshold) {
return this;
}

/**
* Whether to enable the support of multiple image occurrences.
*
* @since Appium 1.21.0
* @return self instance for chaining.
*/
public OccurrenceMatchingOptions enableMultiple() {
this.multiple = true;
return this;
}

/**
* The pixel distance between matches we consider
* to be part of the same template match. This option is only
* considered if multiple matches mode is enabled.
* 10 pixels by default.
*
* @since Appium 1.21.0
* @return self instance for chaining.
*/
public OccurrenceMatchingOptions withMatchNeighbourThreshold(int threshold) {
this.matchNeighbourThreshold = threshold;
return this;
}

@Override
public Map<String, Object> build() {
final ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
builder.putAll(super.build());
ofNullable(threshold).map(x -> builder.put("threshold", x));
ofNullable(matchNeighbourThreshold).map(x -> builder.put("matchNeighbourThreshold", x));
ofNullable(multiple).map(x -> builder.put("multiple", x));
return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,23 @@

import org.openqa.selenium.Rectangle;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class OccurrenceMatchingResult extends ComparisonResult {
private static final String RECT = "rect";
private static final String MULTIPLE = "multiple";

private final boolean isAtRoot;

public OccurrenceMatchingResult(Map<String, Object> input) {
this(input, true);
}

private OccurrenceMatchingResult(Map<String, Object> input, boolean isAtRoot) {
super(input);
this.isAtRoot = isAtRoot;
}

/**
Expand All @@ -37,4 +47,25 @@ public Rectangle getRect() {
//noinspection unchecked
return mapToRect((Map<String, Object>) getCommandResult().get(RECT));
}

/**
* Returns the list of multiple matches (if any).
* This property only works if the `multiple` option is enabled.
*
* @since Appium 1.21.0
* @return The list containing properties of each single match or an empty list.
* @throws IllegalStateException If the accessor is called on a non-root match instance.
*/
public List<OccurrenceMatchingResult> getMultiple() {
if (!isAtRoot) {
throw new IllegalStateException("Only the root match could contain multiple submatches");
}
verifyPropertyPresence(MULTIPLE);

//noinspection unchecked
List<Map<String, Object>> multiple = (List<Map<String, Object>>) getCommandResult().get(MULTIPLE);
return multiple.stream()
.map((m) -> new OccurrenceMatchingResult(m, false))
.collect(Collectors.toList());
}
}

0 comments on commit d5ec15a

Please sign in to comment.