diff --git a/src/main/java/io/percy/appium/lib/ScreenshotOptions.java b/src/main/java/io/percy/appium/lib/ScreenshotOptions.java index d0dda3f..7fe1cec 100644 --- a/src/main/java/io/percy/appium/lib/ScreenshotOptions.java +++ b/src/main/java/io/percy/appium/lib/ScreenshotOptions.java @@ -2,8 +2,9 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; -import io.appium.java_client.MobileElement; +import org.openqa.selenium.WebElement; public class ScreenshotOptions { private String deviceName = null; @@ -15,11 +16,11 @@ public class ScreenshotOptions { private Integer screenLengths = 4; private List ignoreRegionXpaths = new ArrayList(); private List ignoreRegionAccessibilityIds = new ArrayList(); - private List ignoreRegionAppiumElements = new ArrayList(); + private List ignoreRegionAppiumElements = new ArrayList(); private List customIgnoreRegions = new ArrayList(); private List considerRegionXpaths = new ArrayList(); private List considerRegionAccessibilityIds = new ArrayList(); - private List considerRegionAppiumElements = new ArrayList(); + private List considerRegionAppiumElements = new ArrayList(); private List customConsiderRegions = new ArrayList(); private String scrollableXpath = null; private String scrollableId = null; @@ -114,12 +115,12 @@ public void setIgnoreRegionAccessibilityIds(List ignoreRegionAccessibili this.ignoreRegionAccessibilityIds = ignoreRegionAccessibilityIds; } - public List getIgnoreRegionAppiumElements() { + public List getIgnoreRegionAppiumElements() { return ignoreRegionAppiumElements; } - public void setIgnoreRegionAppiumElements(List ignoreRegionAppiumElements) { - this.ignoreRegionAppiumElements = ignoreRegionAppiumElements; + public void setIgnoreRegionAppiumElements(List ignoreRegionAppiumElements) { + this.ignoreRegionAppiumElements = castMobileElementsToWebElements(ignoreRegionAppiumElements); } public List getCustomIgnoreRegions() { @@ -146,12 +147,12 @@ public void setConsiderRegionAccessibilityIds(List considerRegionAccessi this.considerRegionAccessibilityIds = considerRegionAccessibilityIds; } - public List getConsiderRegionAppiumElements() { + public List getConsiderRegionAppiumElements() { return considerRegionAppiumElements; } - public void setConsiderRegionAppiumElements(List considerRegionAppiumElements) { - this.considerRegionAppiumElements = considerRegionAppiumElements; + public void setConsiderRegionAppiumElements(List considerRegionAppiumElements) { + this.considerRegionAppiumElements = castMobileElementsToWebElements(considerRegionAppiumElements); } public List getCustomConsiderRegions() { @@ -177,4 +178,13 @@ public String getScrollableId() { public void setScrollableId(String scrollableId) { this.scrollableId = scrollableId; } + + public List castMobileElementsToWebElements(List mobileElements) { + List webElements = mobileElements.stream() + .filter(obj -> WebElement.class.isAssignableFrom(obj.getClass())) // Check if the object is a WebElement + .map(obj -> (WebElement) obj) // Cast the object to WebElement + .collect(Collectors.toList()); + + return webElements; + } } diff --git a/src/main/java/io/percy/appium/metadata/AndroidMetadata.java b/src/main/java/io/percy/appium/metadata/AndroidMetadata.java index 5e50c64..1dc41bf 100644 --- a/src/main/java/io/percy/appium/metadata/AndroidMetadata.java +++ b/src/main/java/io/percy/appium/metadata/AndroidMetadata.java @@ -2,9 +2,6 @@ import java.util.Map; -import org.openqa.selenium.remote.Response; -import org.openqa.selenium.remote.http.HttpMethod; - import io.appium.java_client.AppiumDriver; import io.appium.java_client.android.AndroidDriver; import io.percy.appium.lib.Cache; @@ -63,21 +60,11 @@ public Integer navBarHeight() { private Map getViewportRect() { if (Cache.CACHE_MAP.get("viewportRect_" + sessionId) == null) { - try { - Cache.CACHE_MAP.put("viewportRect_" + sessionId, getSession().get("viewportRect")); - } catch (java.lang.NoSuchMethodError e) { - Cache.CACHE_MAP.put("viewportRect_" + sessionId, driver.getSessionDetails().get("viewportRect")); - } + Cache.CACHE_MAP.put("viewportRect_" + sessionId, getSession().get("viewportRect")); } return (Map) Cache.CACHE_MAP.get("viewportRect_" + sessionId); } - private Map getSession() { - driver.addCommand(HttpMethod.GET, "/session/" + driver.getSessionId(), "getSession"); - Response session = driver.execute("getSession"); - return (Map) session.getValue(); - } - public Integer scaleFactor() { return 1; } diff --git a/src/main/java/io/percy/appium/metadata/IosMetadata.java b/src/main/java/io/percy/appium/metadata/IosMetadata.java index 6c0090b..8e28291 100644 --- a/src/main/java/io/percy/appium/metadata/IosMetadata.java +++ b/src/main/java/io/percy/appium/metadata/IosMetadata.java @@ -2,9 +2,6 @@ import java.util.Map; -import org.openqa.selenium.remote.Response; -import org.openqa.selenium.remote.http.HttpMethod; - import io.appium.java_client.AppiumDriver; import io.appium.java_client.ios.IOSDriver; import io.percy.appium.lib.Cache; @@ -68,21 +65,11 @@ public Integer statBarHeight() { private Map getViewportRect() { if (Cache.CACHE_MAP.get("viewportRect_" + sessionId) == null) { - try { - Cache.CACHE_MAP.put("viewportRect_" + sessionId, getSession().get("viewportRect")); - } catch (java.lang.NoSuchMethodError e) { - Cache.CACHE_MAP.put("viewportRect_" + sessionId, driver.getSessionDetails().get("viewportRect")); - } + Cache.CACHE_MAP.put("viewportRect_" + sessionId, getSession().get("viewportRect")); } return (Map) Cache.CACHE_MAP.get("viewportRect_" + sessionId); } - private Map getSession() { - driver.addCommand(HttpMethod.GET, "/session/" + driver.getSessionId(), "getSession"); - Response session = driver.execute("getSession"); - return (Map) session.getValue(); - } - public Integer navBarHeight() { Integer navBar = getNavBar(); if (navBar != null) { @@ -92,7 +79,7 @@ public Integer navBarHeight() { } public Integer scaleFactor() { - return Integer.valueOf(driver.getSessionDetails().get("pixelRatio").toString()); + return Integer.valueOf(getSession().get("pixelRatio").toString()); } } diff --git a/src/main/java/io/percy/appium/metadata/Metadata.java b/src/main/java/io/percy/appium/metadata/Metadata.java index f21a2db..047e09a 100644 --- a/src/main/java/io/percy/appium/metadata/Metadata.java +++ b/src/main/java/io/percy/appium/metadata/Metadata.java @@ -1,6 +1,12 @@ package io.percy.appium.metadata; +import java.util.Map; + +import org.openqa.selenium.remote.Response; +import org.openqa.selenium.remote.http.HttpMethod; + import io.appium.java_client.AppiumDriver; +import io.percy.appium.lib.Cache; public abstract class Metadata { private static AppiumDriver driver; @@ -9,6 +15,7 @@ public abstract class Metadata { private Integer statusBar; private Integer navBar; private String deviceName; + private String sessionId; public Metadata(AppiumDriver driver, String deviceName, Integer statusBar, Integer navBar, String orientation, String platformVersion) { @@ -18,6 +25,7 @@ public Metadata(AppiumDriver driver, String deviceName, Integer statusBar, Integ this.statusBar = statusBar; this.navBar = navBar; this.deviceName = deviceName; + this.sessionId = driver.getSessionId().toString(); } public String osName() { @@ -74,6 +82,15 @@ public Integer getStatusBar() { return statusBar; } + public Map getSession() { + if (Cache.CACHE_MAP.get("getSession_" + sessionId) == null) { + driver.addCommand(HttpMethod.GET, "/session/" + driver.getSessionId(), "getSession"); + Response session = driver.execute("getSession"); + Cache.CACHE_MAP.put("getSession_" + sessionId, session.getValue()); + } + return (Map) Cache.CACHE_MAP.get("getSession_" + sessionId); + } + public abstract Integer deviceScreenWidth(); public abstract String deviceName(); diff --git a/src/main/java/io/percy/appium/providers/GenericProvider.java b/src/main/java/io/percy/appium/providers/GenericProvider.java index 75758cb..4878999 100644 --- a/src/main/java/io/percy/appium/providers/GenericProvider.java +++ b/src/main/java/io/percy/appium/providers/GenericProvider.java @@ -12,12 +12,13 @@ import org.apache.commons.codec.binary.Base64; import org.json.JSONArray; import org.json.JSONObject; +import org.openqa.selenium.By; import org.openqa.selenium.Dimension; import org.openqa.selenium.OutputType; import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; import io.appium.java_client.AppiumDriver; -import io.appium.java_client.MobileElement; import io.percy.appium.AppPercy; import io.percy.appium.lib.CliWrapper; import io.percy.appium.lib.Region; @@ -153,7 +154,7 @@ public void setDebugUrl(String debugUrl) { public JSONArray findRegions( List xpaths, List accessibilityIds, - List elements, + List elements, List locations ) { JSONArray elementsArray = new JSONArray(); @@ -165,7 +166,7 @@ public JSONArray findRegions( return elementsArray; } - public JSONObject getRegionObject(String selector, MobileElement element) { + public JSONObject getRegionObject(String selector, WebElement element) { Point location = element.getLocation(); Dimension size = element.getSize(); double scaleFactor = metadata.scaleFactor(); @@ -185,7 +186,7 @@ public JSONObject getRegionObject(String selector, MobileElement element) { public void getRegionsByXpath(JSONArray elementsArray, List xpaths) { for (String xpath : xpaths) { try { - MobileElement element = (MobileElement) driver.findElementByXPath(xpath); + WebElement element = (WebElement) driver.findElement(By.xpath(xpath)); String selector = String.format("xpath: %s", xpath); JSONObject region = getRegionObject(selector, element); elementsArray.put(region); @@ -199,7 +200,7 @@ public void getRegionsByXpath(JSONArray elementsArray, List xpaths) { public void getRegionsByIds(JSONArray elementsArray, List ids) { for (String id : ids) { try { - MobileElement element = (MobileElement) driver.findElementByAccessibilityId(id); + WebElement element = (WebElement) driver.findElement(By.id(id)); String selector = String.format("id: %s", id); JSONObject region = getRegionObject(selector, element); elementsArray.put(region); @@ -211,7 +212,7 @@ public void getRegionsByIds(JSONArray elementsArray, List ids) { } } - public void getRegionsByElements(JSONArray elementsArray, List elements) { + public void getRegionsByElements(JSONArray elementsArray, List elements) { for (int index = 0; index < elements.size(); index++) { try { String type = elements.get(index).getAttribute("class"); diff --git a/src/test/java/io/percy/appium/lib/ScreenshotOptionsTest.java b/src/test/java/io/percy/appium/lib/ScreenshotOptionsTest.java new file mode 100644 index 0000000..b917175 --- /dev/null +++ b/src/test/java/io/percy/appium/lib/ScreenshotOptionsTest.java @@ -0,0 +1,40 @@ +package io.percy.appium.lib; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.WebElement; + +import io.appium.java_client.MobileElement; + +@RunWith(org.mockito.junit.MockitoJUnitRunner.class) +public class ScreenshotOptionsTest { + @Test + public void testCastMobileElementsToWebElements() { + ScreenshotOptions casting = new ScreenshotOptions(); + + // Create a list of MobileElements + List mobileElements = new ArrayList<>(); + mobileElements.add(new MobileElement() {}); + mobileElements.add(new Object()); + mobileElements.add(new Object()); + mobileElements.add(new MobileElement() {}); + mobileElements.add(new MobileElement() {}); + + // Call the function to cast them to WebElements + List webElements = casting.castMobileElementsToWebElements(mobileElements); + + // Check if the sizes of the original and converted lists are the same + assertEquals(webElements.size(), 3); + + // Check that each element in the converted list is an instance of WebElement + for (WebElement element : webElements) { + assertTrue(element instanceof WebElement); + } + } +} diff --git a/src/test/java/io/percy/appium/metadata/IosMetadataTest.java b/src/test/java/io/percy/appium/metadata/IosMetadataTest.java index d536898..2804b78 100644 --- a/src/test/java/io/percy/appium/metadata/IosMetadataTest.java +++ b/src/test/java/io/percy/appium/metadata/IosMetadataTest.java @@ -34,13 +34,14 @@ public class IosMetadataTest { Capabilities capabilities; HashMap viewportRect = new HashMap(); - HashMap> sessionValue = new HashMap>(); + HashMap sessionValue = new HashMap<>(); Response session = new Response(new SessionId("abc")); Faker faker = new Faker(); Long width = faker.number().randomNumber(3, false); Long top = faker.number().randomNumber(3, false); Long height = faker.number().randomNumber(3, false); + Long pixelRatio = faker.number().randomNumber(1, false); @Before public void setup() { @@ -48,6 +49,7 @@ public void setup() { viewportRect.put("top", top); viewportRect.put("height", height); sessionValue.put("viewportRect", viewportRect); + sessionValue.put("pixelRatio", pixelRatio); session.setValue(sessionValue); when(driver.execute("getSession")).thenReturn(session); when(driver.getCapabilities()).thenReturn(capabilities); @@ -170,9 +172,9 @@ public void testOrientatioAuto() { @Test public void testScaleFactor() { + Cache.CACHE_MAP.clear(); Map details = new HashMap<>(); details.put("pixelRatio", 2); - when(driver.getSessionDetails()).thenReturn(details); - Assert.assertEquals(metadata.scaleFactor().intValue(), 2); + Assert.assertEquals(metadata.scaleFactor().intValue(), pixelRatio.intValue()); } } diff --git a/src/test/java/io/percy/appium/providers/GenericProviderTest.java b/src/test/java/io/percy/appium/providers/GenericProviderTest.java index 1f34316..5ea200e 100644 --- a/src/test/java/io/percy/appium/providers/GenericProviderTest.java +++ b/src/test/java/io/percy/appium/providers/GenericProviderTest.java @@ -24,10 +24,12 @@ import org.junit.runner.RunWith; import org.mockito.Mock; +import org.openqa.selenium.By; import org.openqa.selenium.Capabilities; import org.openqa.selenium.Dimension; import org.openqa.selenium.OutputType; import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.SessionId; @@ -42,7 +44,7 @@ public class GenericProviderTest { Capabilities capabilities; @Mock - MobileElement mockElement; + WebElement mockElement; Faker faker = new Faker(); Long top = faker.number().randomNumber(3, false); @@ -146,7 +148,7 @@ public void testGetRegionsByXpath() { Point location = new Point(10, 20); Dimension size = new Dimension(100, 200); - when(androidDriver.findElementByXPath("//div[@class='example']")).thenReturn(mockElement); + when(androidDriver.findElement(By.xpath("//div[@class='example']"))).thenReturn(mockElement); when(mockElement.getLocation()).thenReturn(location); when(mockElement.getSize()).thenReturn(size); @@ -156,7 +158,7 @@ public void testGetRegionsByXpath() { genericProvider.getRegionsByXpath(elementsArray, xpaths); - verify(androidDriver).findElementByXPath("//div[@class='example']"); + verify(androidDriver).findElement(By.xpath("//div[@class='example']")); JSONObject region = elementsArray.getJSONObject(0); Assert.assertEquals("xpath: //div[@class='example']", region.get("selector")); JSONObject coOrdinates = region.getJSONObject("co_ordinates"); @@ -175,7 +177,7 @@ public void testGetRegionsByIds() { Point location = new Point(10, 20); Dimension size = new Dimension(100, 200); - when(androidDriver.findElementByAccessibilityId("some id")).thenReturn(mockElement); + when(androidDriver.findElement(By.id("some id"))).thenReturn(mockElement); when(mockElement.getLocation()).thenReturn(location); when(mockElement.getSize()).thenReturn(size); @@ -185,7 +187,7 @@ public void testGetRegionsByIds() { genericProvider.getRegionsByIds(elementsArray, ids); - verify(androidDriver).findElementByAccessibilityId("some id"); + verify(androidDriver).findElement(By.id("some id")); JSONObject region = elementsArray.getJSONObject(0); Assert.assertEquals("id: some id", region.get("selector")); JSONObject coOrdinates = region.getJSONObject("co_ordinates"); @@ -200,7 +202,7 @@ public void testGetRegionsByElement() { JSONArray elementsArray = new JSONArray(); Point location = new Point(10, 20); Dimension size = new Dimension(100, 200); - List elements = new ArrayList<>(); + List elements = new ArrayList<>(); when(mockElement.getLocation()).thenReturn(location); when(mockElement.getSize()).thenReturn(size); when(mockElement.getAttribute("class")).thenReturn("Button");