Skip to content

Commit

Permalink
[robot] attempt windows scroll pattern #1604
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrthomas committed May 28, 2021
1 parent ca0675c commit 1022872
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 7 deletions.
11 changes: 11 additions & 0 deletions karate-robot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
| <a href="#select"><code>select()</code></a>
| <a href="#highlight"><code>highlight()</code></a>
| <a href="#highlightall"><code>highlightAll()</code></a>
| <a href="#scroll"><code>scroll()</code></a>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -757,6 +758,16 @@ Note that you can call this *on* an [`Element`](#element-api) instance if you re
* locate('//pane{Tree}').screenshot()
```

## `scroll()`
The following methods are available only *on* Windows `Element`-s. Note that they will work only if the "[Scroll Pattern](https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nn-uiautomationclient-iuiautomationscrollpattern)" is available.

> Note that `scroll()` has not been tested, please contribute if you can. Also refer to the [diff]() as an example of how to add an un-implemented "pattern" to `karate-robot`.
### `scroll(horizontalPercent, verticalPercent)`
### `scrollUp()`
### `scrollDown()`
Both `scrollUp()` and `scrollDown()` take an optional boolean argument to specify if a "large" increment should be used, e.g: `scrollDown(true)`.

## `screenshotActive()`
This will screenshot only the [active](#robotactive) control, typically the [window](#window) having focus.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ private <T> T get(String key, T defaultValue) {
return temp == null ? defaultValue : temp;
}

public Logger getLogger() {
return logger;
}

public RobotBase(ScenarioRuntime runtime) {
this(runtime, Collections.EMPTY_MAP);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package com.intuit.karate.robot.win;

import com.sun.jna.Function;
import com.sun.jna.ptr.DoubleByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import java.util.ArrayList;
Expand Down Expand Up @@ -53,10 +54,10 @@ public IUIAutomationBase(PointerByReference ref) {
protected static int enumValue(String name, String key) {
return ComUtils.enumValue(name, key);
}

protected static String enumKey(String name, int value) {
return ComUtils.enumKey(name, value);
}
}

public int invoke(int offset, Object... args) {
Function function = INTERFACE.getFunction(offset, REF.getValue());
Expand Down Expand Up @@ -139,7 +140,7 @@ public IUIAutomationCondition invokeForCondition(String name, Object... args) {

public String invokeForString(String name) {
ComRef ref = new ComRef();
invoke(name, ref);
invoke(name, ref);
return ref.isNull() ? "" : ref.asString();
}

Expand All @@ -148,9 +149,15 @@ public int invokeForInt(String name) {
invoke(name, ref);
return ref.getValue();
}

public boolean invokeForBool(String name) {
return invokeForInt(name) != 0;
}
}

public double invokeForDouble(String name) {
DoubleByReference ref = new DoubleByReference();
invoke(name, ref);
return ref.getValue();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* The MIT License
*
* Copyright 2021 Intuit Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.intuit.karate.robot.win;

/**
*
* @author pthomas3
*/
public class IUIAutomationScrollPattern extends IUIAutomationBase {

public boolean getCurrentHorizontallyScrollable() {
return invokeForBool("CurrentHorizontallyScrollable");
}

public double getCurrentHorizontalScrollPercent() {
return invokeForDouble("CurrentHorizontalScrollPercent");
}

public double getCurrentHorizontalViewSize() {
return invokeForDouble("CurrentHorizontalViewSize");
}

public boolean getCurrentVerticallyScrollable() {
return invokeForBool("CurrentVerticallyScrollable");
}

public double getCurrentVerticalScrollPercent() {
return invokeForDouble("CurrentVerticalScrollPercent");
}

public double getCurrentVerticalViewSize() {
return invokeForDouble("CurrentVerticalViewSize");
}

public void scroll(ScrollAmount scrollAmount) {
invoke("Scroll", scrollAmount.value);
}

public void setScrollPercent(double horizontalPercent, double verticalPercent) {
invoke("SetScrollPercent", horizontalPercent, verticalPercent);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public enum Pattern {
Selection(10001),
Value(10002, IUIAutomationValuePattern.class),
RangeValue(10003),
Scroll(10004),
Scroll(10004, IUIAutomationScrollPattern.class),
ExpandCollapse(10005),
Grid(10006),
GridItem(10007),
Expand Down Expand Up @@ -97,7 +97,7 @@ private Pattern(int value, Class type) {
public static Pattern fromType(Class type) {
return FROM_CLASS.get(type.getSimpleName());
}

public static Pattern fromName(String name) {
return FROM_NAME.get(name.toLowerCase());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* The MIT License
*
* Copyright 2021 Intuit Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.intuit.karate.robot.win;

/**
*
* @author pthomas3
*/
public enum ScrollAmount {

LargeDecrement(0),
SmallDecrement(1),
NoAmount(2),
LargeIncrement(3),
SmallIncrement(4);

public final int value;

private ScrollAmount(int value) {
this.value = value;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
package com.intuit.karate.robot.win;

import com.intuit.karate.Logger;
import com.intuit.karate.robot.Element;
import com.intuit.karate.robot.Location;
import com.intuit.karate.robot.Region;
Expand All @@ -40,10 +41,12 @@ public class WinElement implements Element {

protected final IUIAutomationElement e;
private final WinRobot robot;
private final Logger logger;

public WinElement(WinRobot robot, IUIAutomationElement e) {
this.robot = robot;
this.e = e;
this.logger = robot.getLogger();
}

@Override
Expand Down Expand Up @@ -132,6 +135,11 @@ private boolean isInvokePatternAvailable() {
return variant.booleanValue();
}

private boolean isScrollPatternAvailable() {
Variant.VARIANT variant = e.getCurrentPropertyValue(Property.IsScrollPatternAvailable);
return variant.booleanValue();
}

@Override
public String getValue() {
if (isValuePatternAvailable()) {
Expand Down Expand Up @@ -248,6 +256,46 @@ public Element select() {
return this;
}

public Element scrollDown() {
return scrollDown(false);
}

public Element scrollUp() {
return scrollUp(false);
}

public Element scrollDown(boolean large) {
if (isScrollPatternAvailable()) {
IUIAutomationScrollPattern pattern = e.getCurrentPattern(IUIAutomationScrollPattern.class);
ScrollAmount sa = large ? ScrollAmount.LargeIncrement : ScrollAmount.SmallIncrement;
pattern.scroll(sa);
} else {
logger.warn("scroll pattern not available on: {}", getName());
}
return this;
}

public Element scrollUp(boolean large) {
if (isScrollPatternAvailable()) {
IUIAutomationScrollPattern pattern = e.getCurrentPattern(IUIAutomationScrollPattern.class);
ScrollAmount sa = large ? ScrollAmount.LargeDecrement : ScrollAmount.SmallDecrement;
pattern.scroll(sa);
} else {
logger.warn("scroll pattern not available on: {}", getName());
}
return this;
}

public Element scroll(double horizontalPercent, double verticalPercent) {
if (isScrollPatternAvailable()) {
IUIAutomationScrollPattern pattern = e.getCurrentPattern(IUIAutomationScrollPattern.class);
pattern.setScrollPercent(horizontalPercent, verticalPercent);
} else {
logger.warn("scroll pattern not available on: {}", getName());
}
return this;
}

public Object as(String patternName) {
Pattern pattern = Pattern.fromName(patternName);
if (pattern == null) {
Expand Down

0 comments on commit 1022872

Please sign in to comment.