appium / appium/java-client

java.lang.ClassCastException: com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to java.lang.String

Open
#1,510 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.3k
Forks
752
Avg merge
6d 21h
Merged PRs (30d)
8

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ComparisonResult.java, especially getVisualization at line 63 and storeVisualization at line 73, then compare their behavior with the exception and the res.storeVisualization(failViz) call in the reproduction. Confirm the image-comparison failure path can save the visualization without the reported ClassCastException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.