java-client
java-client copied to clipboard
java.lang.ClassCastException: com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to java.lang.String
Description
I use the image comparison feature of appium and since last update of appium, saving the comparison result picture when a failure occure is broken and throws an exception. The comparison itself does work correctly. It throws the ecception on this function
res.storeVisualization(failViz);
I have checked the code in github and it looks like that in the class "ComparisonResult.java" line 63 a map is casted to String.
return ((String) getCommandResult().get(VISUALIZATION)).getBytes(StandardCharsets.UTF_8);
Environment
- Java client build version : 7.4.1
- Appium server version or git revision : 1.21.0
- Desktop OS/version used to run Appium if necessary: MacOs Big Sur
- Node.js : 12.19.1
- Mobile platform/version under test: ios / Android
- Real device or emulator/simulator: Simulator
Details
Please provide more details, if necessary.
Code To Reproduce Issue [ Good To Have ]
public static void doVisualCheckByELement(String locatorType, String locator, String checkName, double MATCH_THRESHOLD, String baseline) throws Exception {
waitTime(1000);
final String dir = System.getProperty("user.dir");
File VALIDATION_PATH = new File(dir+"/src/test/resources/TestData/compareScrn");
// File VALIDATION_ERROR_PATH = new File(dir+"/src/test/resources/TestData/compareScrn");
File f = new File(dir+"/appium_screenshots/"+NameOfClass);
File folder = new File(dir+"/appium_screenshots");
try
{
if(folder.mkdir())
{
sysLogger("debug", "Appium_screenshots Directory Created for screenComparison Failures");
}
else
{
sysLogger("debug", "Appium_screenshots Directory is not created for screenComparison Failures");
}
} catch(Exception e)
{
e.printStackTrace();
}
try
{
if(f.mkdir())
{
sysLogger("debug", "Directory Created for screenComparison Failures");
}
else
{
sysLogger("debug", "Directory is not created for screenComparison Failures");
}
} catch(Exception e)
{
e.printStackTrace();
}
String baselineFilename = VALIDATION_PATH + "/" + NameOfClass+"_"+baseline +"_"+ checkName + ".png";
File baselineImg = new File(baselineFilename);
// If no baseline image exists for this check, we should create a baseline image
if (!baselineImg.exists()) {
sysLogger("debug", String.format("No baseline found for '%s' check; capturing baseline instead of checking", checkName));
File newBaseline = TestFlow.driver.getScreenshotAs(OutputType.FILE);
MobileElement element = (MobileElement) Helpers.find(locatorType, locator, 3, false);
BufferedImage newBase= Helpers.generateImage(element, newBaseline);
File outputfile = new File(baselineFilename);
ImageIO.write(newBase, "png", outputfile); // FileUtils.copyFile(newBase, new File(baselineFilename));
return;
}
// Otherwise, if we found a baseline, get the image similarity from Appium. In getting the similarity,
// we also turn on visualization so we can see what went wrong if something did.
SimilarityMatchingOptions opts = new SimilarityMatchingOptions();
opts.withEnabledVisualization();
File newBaseline = TestFlow.driver.getScreenshotAs(OutputType.FILE);
MobileElement element = (MobileElement) Helpers.find(locatorType, locator, 3, false);
BufferedImage newBase=Helpers.generateImage(element, newBaseline);
SimilarityMatchingResult res = TestFlow.driver.getImagesSimilarity(baselineImg, newBaseline, opts);
// If the similarity is not high enough, consider the check to have failed
if (res.getScore() < MATCH_THRESHOLD)
{
File failViz = new File(dir+"/appium_screenshots/"+NameOfClass+"/FAIL_" + NameOfClass + "_" + baseline +"_"+ checkName + ".png");
try {
res.storeVisualization(failViz);
} catch (ClassCastException e) {
e.printStackTrace();
}
TestFlow.lastScreenshotSaveDir=dir+"/appium_screenshots/"+NameOfClass+"/FAIL_" + NameOfClass + "_" +baseline +"_"+ checkName + ".png";
String abc= String.format("Visual check of '%s' failed; similarity match was only %f, and below the threshold of %f. Visualization written to %s.",
checkName, res.getScore(), MATCH_THRESHOLD, failViz.getAbsolutePath());
Assert.fail(abc);
}
// Otherwise, it passed!
sysLogger("debug", String.format("Visual check of '%s' passed; similarity match was %f",checkName, res.getScore()));
}
Exception Stacktraces
java.lang.ClassCastException: com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to java.lang.String at io.appium.java_client.imagecomparison.ComparisonResult.getVisualization(ComparisonResult.java:63) at io.appium.java_client.imagecomparison.ComparisonResult.storeVisualization(ComparisonResult.java:73) at iOS_ross.helpers.ImageCompare.doVisualCheckByELement(ImageCompare.java:168) at iOS_ross.Promotions_Test.promotion_multiplePictures_zoom(Promotions_Test.java:201) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365) at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:272) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:236) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:386) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:323) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:143)
Link To Appium Logs
logs don't give any more informations
There's a known bug in the Appium server code. Try appium@beta or appium@rc instead
Thanks, do you know if that will be also fixed than in appium 2.0 which will hopefully be released in next weeks ?
In v2.0 this code has been moved to a separate plugin and the recent version of it should have the fix