# When trying to get context handles in iOS, throws an exception

**URL:** <https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679>\
**Category:** Support\
**Created:** [June 24, 2022, 12:08pm UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679 "2022-06-24T12:08:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmj](https://discuss.appium.io/user_avatar/discuss.appium.io/jmj/32/9372_2.png) [@jmj](https://discuss.appium.io/u/jmj)\
**Post date:** [June 24, 2022, 12:08pm UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679/1 "2022-06-24T12:08:10Z")

</div>

When trying to get context handles in iOS, throws an exception.

`java.lang.ClassCastException: class com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to class java.lang.String (com.google.common.collect.Maps$TransformedEntriesMap is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')`

Steps I m trying to achieve

1. Open the app and perform some operations
2. Then switch to Safari browser and perform operations

Below is the sample code snippet

```
((IOSDriver)driver).activateApp("com.apple.mobilesafari");
Set<String> contexts = ((IOSDriver) driver).getContextHandles();
for(String handle:contexts)
{
    System.out.println(handle);
}

```

I have also added capabilities related to webview as well

```
        capabilities.setCapability("fullContextList", true);
        capabilities.setCapability("includeSafariInWebviews","true");

```

Appium java client version 8.0.0  
Appium version 1.22.0

---

<div class="post-metadata">

**Author:** ![wreed](https://discuss.appium.io/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wreed](https://discuss.appium.io/u/wreed)\
**Post date:** [June 24, 2022, 4:26pm UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679/2 "2022-06-24T16:26:06Z")

</div>

> [@jmj](#):
>
> java.lang.ClassCastException: class com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to class java.lang.String

I think you are running into a bug in java-client:

> <https://github.com/appium/java-client/issues/1510>
>
> \## Description
> 
> I use the image comparison feature of appium and since last up…date 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

---

<div class="post-metadata">

**Author:** ![mykola-mokhnach](https://discuss.appium.io/user_avatar/discuss.appium.io/mykola-mokhnach/32/4578_2.png) [@mykola-mokhnach](https://discuss.appium.io/u/mykola-mokhnach)\
**Post date:** [June 24, 2022, 5:55pm UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679/3 "2022-06-24T17:55:36Z")

</div>

I assume this is expected with strict typing. Try to use [https://github.com/appium/appium-xcuitest-driver#mobile-getcontexts](https://github.com/appium/appium-xcuitest-driver#mobile-getcontexts) instead to fetch extended contexts info

---

<div class="post-metadata">

**Author:** ![jmj](https://discuss.appium.io/user_avatar/discuss.appium.io/jmj/32/9372_2.png) [@jmj](https://discuss.appium.io/u/jmj)\
**Post date:** [June 27, 2022, 7:39am UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679/4 "2022-06-27T07:39:14Z")

</div>

in one of the comments, it says

In v2.0 this code has been moved to a separate plugin and the recent version of it should have the fix

Where can I find this plugin?

---

<div class="post-metadata">

**Author:** ![wreed](https://discuss.appium.io/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wreed](https://discuss.appium.io/u/wreed)\
**Post date:** [June 27, 2022, 2:58pm UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679/5 "2022-06-27T14:58:54Z")

</div>

I don’t know what plugin/where it is, but perhaps you should direct your question to the commenter, who happens to be a commenter in this thread too.

---

<div class="post-metadata">

**Author:** ![buseco](https://discuss.appium.io/user_avatar/discuss.appium.io/buseco/32/10205_2.png) [@buseco](https://discuss.appium.io/u/buseco)\
**Post date:** [January 11, 2023, 5:19pm UTC](https://discuss.appium.io/t/when-trying-to-get-context-handles-in-ios-throws-an-exception/36679/8 "2023-01-11T17:19:14Z")

</div>

Removing this capability will solve it:

> [@jmj](#):
>
> capabilities.setCapability(“fullContextList”, true);

You’ll get a plain string without this. This capability will include more information for each context.
