Skip to content

Commit

Permalink
Fix orientation change bug (#167)
Browse files Browse the repository at this point in the history
* Fix orientation change bug that causes stat bar and nav bar height to wrong values

* removed comment
  • Loading branch information
prklm10 authored Feb 9, 2024
1 parent 91d92f4 commit d1ebb85
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 29 deletions.
38 changes: 38 additions & 0 deletions src/main/java/io/percy/appium/lib/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.percy.appium.lib;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.percy.appium.AppPercy;

public class Utils {
public static Integer extractStatusBarHeight(String input) {
try {
Pattern pattern = Pattern.compile("ITYPE_STATUS_BAR frame=\\[\\d+,\\d+\\]\\[\\d+,([\\d]+)\\]");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
return Integer.parseInt(matcher.group(1));
}
return null; // Return null if no match found
} catch (Exception ex) {
AppPercy.log(ex.toString(), "debug");
return null; // Return null if any error
}
}

public static Integer extractNavigationBarHeight(String input) {
try {
Pattern pattern = Pattern.compile("ITYPE_NAVIGATION_BAR frame=\\[\\d+,([\\d]+)\\]\\[\\d+,([\\d]+)\\]");
Matcher matcher = pattern.matcher(input);

if (matcher.find()) {
int bottomCoordinate = Integer.parseInt(matcher.group(1));
int topCoordinate = Integer.parseInt(matcher.group(2));
return topCoordinate - bottomCoordinate;
}
return null; // Return null if no match found
} catch (Exception ex) {
AppPercy.log(ex.toString(), "debug");
return null; // Return null if any error
}
}
}
27 changes: 27 additions & 0 deletions src/main/java/io/percy/appium/metadata/AndroidMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

import java.util.Map;

import org.json.JSONObject;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.percy.appium.lib.Cache;
import io.percy.appium.lib.Utils;

public class AndroidMetadata extends Metadata {
private AndroidDriver driver;
private String sessionId;
private String orientation;

public AndroidMetadata(AppiumDriver driver, String deviceName, Integer statusBar, Integer navBar,
String orientation, String platformVersion) {
super(driver, deviceName, statusBar, navBar, orientation, platformVersion);
this.driver = (AndroidDriver) driver;
this.orientation = orientation;
this.sessionId = driver.getSessionId().toString();
}

Expand Down Expand Up @@ -41,7 +46,11 @@ public Integer deviceScreenHeight() {
}

public Integer statBarHeight() {

Integer statBar = getStatusBar();
if (statBar == null && orientation != null && orientation.toLowerCase().equals("auto")) {
statBar = Utils.extractStatusBarHeight(getDisplaySysDump());
}
if (statBar != null) {
return statBar;
}
Expand All @@ -50,6 +59,9 @@ public Integer statBarHeight() {

public Integer navBarHeight() {
Integer navBar = getNavBar();
if (navBar == null && orientation != null && orientation.toLowerCase().equals("auto")) {
navBar = Utils.extractNavigationBarHeight(getDisplaySysDump());
}
if (navBar != null) {
return navBar;
}
Expand All @@ -69,4 +81,19 @@ public Integer scaleFactor() {
return 1;
}

public String getDisplaySysDump() {
if (Cache.CACHE_MAP.get("getDisplaySysDump_" + sessionId) == null) {

JSONObject arguments = new JSONObject();
arguments.put("action", "adbShell");
JSONObject command = new JSONObject();
command.put("command", "dumpsys window displays");
arguments.put("arguments", command);
String resultString = driver
.executeScript(String.format("browserstack_executor: %s", arguments.toString())).toString();
Cache.CACHE_MAP.put("getDisplaySysDump_" + sessionId, resultString);
}
return (String) Cache.CACHE_MAP.get("getDisplaySysDump_" + sessionId);
}

}
46 changes: 22 additions & 24 deletions src/main/java/io/percy/appium/providers/GenericProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,29 +115,28 @@ public JSONObject screenshot(String name, ScreenshotOptions options,
String platformVersion, String deviceName) throws Exception {
this.metadata = MetadataHelper.resolve(driver, deviceName, options.getStatusBarHeight(),
options.getNavBarHeight(), options.getOrientation(), platformVersion);
JSONObject tag = getTag();
List<Tile> tiles = captureTiles(options);
// Get Tag After captureTile. This is done if orientation is auto.
// Orientation get overwrited in metadata.orientation() function.
JSONObject tag = getTag();
JSONArray ignoreRegions = findRegions(
options.getIgnoreRegionXpaths(),
options.getIgnoreRegionAccessibilityIds(),
options.getIgnoreRegionAppiumElements(),
options.getCustomIgnoreRegions()
);
options.getIgnoreRegionXpaths(),
options.getIgnoreRegionAccessibilityIds(),
options.getIgnoreRegionAppiumElements(),
options.getCustomIgnoreRegions());
JSONArray considerRegions = findRegions(
options.getConsiderRegionXpaths(),
options.getConsiderRegionAccessibilityIds(),
options.getConsiderRegionAppiumElements(),
options.getCustomConsiderRegions()
);
options.getConsiderRegionXpaths(),
options.getConsiderRegionAccessibilityIds(),
options.getConsiderRegionAppiumElements(),
options.getCustomConsiderRegions());
return cliWrapper.postScreenshot(
name,
tag,
tiles,
debugUrl,
getObjectForArray("ignoreElementsData", ignoreRegions),
getObjectForArray("considerElementsData", considerRegions),
options.getSync()
);
name,
tag,
tiles,
debugUrl,
getObjectForArray("ignoreElementsData", ignoreRegions),
getObjectForArray("considerElementsData", considerRegions),
options.getSync());
}

public void setMetadata(Metadata metadata) {
Expand All @@ -153,11 +152,10 @@ public void setDebugUrl(String debugUrl) {
}

public JSONArray findRegions(
List<String> xpaths,
List<String> accessibilityIds,
List<WebElement> elements,
List<Region> locations
) {
List<String> xpaths,
List<String> accessibilityIds,
List<WebElement> elements,
List<Region> locations) {
JSONArray elementsArray = new JSONArray();
getRegionsByXpath(elementsArray, xpaths);
getRegionsByIds(elementsArray, accessibilityIds);
Expand Down
49 changes: 49 additions & 0 deletions src/test/java/io/percy/appium/lib/UtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.percy.appium.lib;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class UtilsTest {
@Test
public void testExtractStatusBarHeighWhenPatternIsPresent() {
String input = "InsetsSource type=ITYPE_STATUS_BAR frame=[0,0][2400,74] visible=true\n" +
"InsetsSource type=ITYPE_NAVIGATION_BAR frame=[0,2358][1080,2400] visible=true";

int expectedStatBarHeight = 74;
int actualStatBarHeight = Utils.extractStatusBarHeight(input);

assertEquals(expectedStatBarHeight, actualStatBarHeight);
}

@Test
public void testExtractNavigationBarHeightWhenPatternIsPresent() {
String input = "InsetsSource type=ITYPE_STATUS_BAR frame=[0,0][2400,74] visible=true\n" +
"InsetsSource type=ITYPE_NAVIGATION_BAR frame=[0,2358][1080,2400] visible=true";

int expectedNavBarHeight = 42;
int actualNavBarHeight = Utils.extractNavigationBarHeight(input);

assertEquals(expectedNavBarHeight, actualNavBarHeight);
}

@Test
public void testExtractStatusBarHeighWhenPatternIsNotPresent() {
String input = "RANDOM frame=[0,0][2400,74] visible=true\n" +
"RANDOM frame=[0,2358][1080,2400] visible=true";

Integer actualStatBarHeight = Utils.extractStatusBarHeight(input);

assertEquals(null, actualStatBarHeight);
}

@Test
public void testExtractNavigationBarHeightWhenPatternIsNotPresent() {
String input = "RANDOM [0,0][2400,74] visible=true\n" +
"RANDOM [0,2358][1080,2400] visible=true";

Integer actualNavBarHeight = Utils.extractNavigationBarHeight(input);

assertEquals(null, actualNavBarHeight);
}
}
63 changes: 58 additions & 5 deletions src/test/java/io/percy/appium/metadata/AndroidMetadataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
Expand Down Expand Up @@ -73,33 +74,85 @@ public void testStatBarHeight() {
Assert.assertEquals(metadata.statBarHeight().intValue(), top.intValue());
}

@Test
public void testStatBarHeightWhenValueGiven() {
metadata = new AndroidMetadata(androidDriver, "Samsung Galaxy s22", 100, 200, "auto", null);
Assert.assertEquals(metadata.statBarHeight().intValue(), 100);
}

@Test
public void testStatBarHeightForAuto() {
metadata = new AndroidMetadata(androidDriver, "Samsung Galaxy s22", null, null, "auto", null);
JSONObject arguments = new JSONObject();
arguments.put("action", "adbShell");
JSONObject command = new JSONObject();
command.put("command", "dumpsys window displays");
arguments.put("arguments", command);

String response = "InsetsSource type=ITYPE_STATUS_BAR frame=[0,0][2400,74] visible=true\n" +
"InsetsSource type=ITYPE_NAVIGATION_BAR frame=[0,2358][1080,2400] visible=true";

when(androidDriver.executeScript(String.format("browserstack_executor: %s", arguments.toString())))
.thenReturn(response);

Integer expectedStatBarHeight = 74;
Integer actualStatBarHeight = metadata.statBarHeight();
Assert.assertEquals(expectedStatBarHeight, actualStatBarHeight);
}

@Test
public void testNavBarHeight() {
Assert.assertEquals(metadata.navBarHeight().intValue(), 2160 - (height + top));
}

@Test
public void testDeviceName(){
public void testNavBarHeightWhenValueGiven() {
metadata = new AndroidMetadata(androidDriver, "Samsung Galaxy s22", 100, 200, "auto", null);
Assert.assertEquals(metadata.navBarHeight().intValue(), 200);
}

@Test
public void testNavBarHeightForAuto() {
metadata = new AndroidMetadata(androidDriver, "Samsung Galaxy s22", null, null, "auto", null);
JSONObject arguments = new JSONObject();
arguments.put("action", "adbShell");
JSONObject command = new JSONObject();
command.put("command", "dumpsys window displays");
arguments.put("arguments", command);

String response = "InsetsSource type=ITYPE_STATUS_BAR frame=[0,0][2400,74] visible=true\n" +
"InsetsSource type=ITYPE_NAVIGATION_BAR frame=[0,2358][1080,2400] visible=true";

when(androidDriver.executeScript(String.format("browserstack_executor: %s", arguments.toString())))
.thenReturn(response);

Integer expectedStatBarHeight = 42;
Integer actualStatBarHeight = metadata.navBarHeight();
Assert.assertEquals(expectedStatBarHeight, actualStatBarHeight);
}

@Test
public void testDeviceName() {
when(capabilities.getCapability("device")).thenReturn("Samsung Galaxy s22");
Assert.assertEquals(metadata.deviceName(), "Samsung Galaxy s22");
}

@Test
public void testDeviceNameFromDesired(){
public void testDeviceNameFromDesired() {
Map desired = new HashMap<>();
desired.put("deviceName", "Samsung Galaxy s22");
when(capabilities.getCapability("desired")).thenReturn(desired);
Assert.assertEquals(metadata.deviceName(), "Samsung Galaxy s22");
}

@Test
public void testOsName(){
public void testOsName() {
when(capabilities.getCapability("platformName")).thenReturn("Android");
Assert.assertEquals(metadata.osName(), "Android");
}

@Test
public void testPlatformVersion(){
public void testPlatformVersion() {
when(capabilities.getCapability("platformVersion")).thenReturn("12");
Assert.assertEquals(metadata.platformVersion(), "12");
}
Expand Down Expand Up @@ -142,7 +195,7 @@ public void testScaleFactor() {
}

@Test
public void testOrientatioWithNullParamAndCaps(){
public void testOrientatioWithNullParamAndCaps() {
when(androidDriver.getCapabilities().getCapability("orientation")).thenReturn(ScreenOrientation.LANDSCAPE);
Assert.assertEquals(metadata.orientation(), "landscape");
}
Expand Down

0 comments on commit d1ebb85

Please sign in to comment.