[image_picker] Set up XCUITests (#3254)

diff --git a/.cirrus.yml b/.cirrus.yml
index 8c632a0..685daca 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -163,7 +163,7 @@
     - name: build-ipas+drive-examples
       env:
         PATH: $PATH:/usr/local/bin
-        PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,image_picker/image_picker,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,quick_actions,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,wifi_info_flutter/wifi_info_flutter"
+        PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,quick_actions,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,wifi_info_flutter/wifi_info_flutter"
         matrix:
           PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4"
           PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4"
diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md
index 0fb0ce4..26e8b10 100644
--- a/packages/image_picker/image_picker/CHANGELOG.md
+++ b/packages/image_picker/image_picker/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.7+14
+
+* Set up XCUITests.
+
 ## 0.6.7+13
 
 * Update documentation of `getImage()` about HEIC images.
diff --git a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj
index 106d49c..be3d55f 100644
--- a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj
@@ -13,6 +13,7 @@
 		680049272280D79A006DD6AB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
 		680049382280F2B9006DD6AB /* pngImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 680049352280F2B8006DD6AB /* pngImage.png */; };
 		680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 680049362280F2B8006DD6AB /* jpgImage.jpg */; };
+		6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */; };
 		68B9AF72243E4B3F00927CE4 /* ImagePickerPluginTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */; };
 		68F4B464228B3AB500C25614 /* PhotoAssetUtilTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68F4B463228B3AB500C25614 /* PhotoAssetUtilTests.m */; };
 		978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
@@ -34,6 +35,13 @@
 			remoteGlobalIDString = 97C146ED1CF9000F007C117D;
 			remoteInfo = Runner;
 		};
+		6801C83B2555D726009DAF8D /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 97C146ED1CF9000F007C117D;
+			remoteInfo = Runner;
+		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -60,6 +68,9 @@
 		680049352280F2B8006DD6AB /* pngImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pngImage.png; sourceTree = "<group>"; };
 		680049362280F2B8006DD6AB /* jpgImage.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = jpgImage.jpg; sourceTree = "<group>"; };
 		6801632E632668F4349764C9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+		6801C8362555D726009DAF8D /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagePickerFromGalleryUITests.m; sourceTree = "<group>"; };
+		6801C83A2555D726009DAF8D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ImagePickerPluginTests.m; path = ../../../ios/Tests/ImagePickerPluginTests.m; sourceTree = "<group>"; };
 		68F4B463228B3AB500C25614 /* PhotoAssetUtilTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = PhotoAssetUtilTests.m; path = ../../../ios/Tests/PhotoAssetUtilTests.m; sourceTree = "<group>"; };
 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@@ -88,6 +99,13 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		6801C8332555D726009DAF8D /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		97C146EB1CF9000F007C117D /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
@@ -123,6 +141,15 @@
 			path = TestImages;
 			sourceTree = "<group>";
 		};
+		6801C8372555D726009DAF8D /* RunnerUITests */ = {
+			isa = PBXGroup;
+			children = (
+				6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */,
+				6801C83A2555D726009DAF8D /* Info.plist */,
+			);
+			path = RunnerUITests;
+			sourceTree = "<group>";
+		};
 		840012C8B5EDBCF56B0E4AC1 /* Pods */ = {
 			isa = PBXGroup;
 			children = (
@@ -150,6 +177,7 @@
 				9740EEB11CF90186004384FC /* Flutter */,
 				97C146F01CF9000F007C117D /* Runner */,
 				680049182280D368006DD6AB /* image_picker_exampleTests */,
+				6801C8372555D726009DAF8D /* RunnerUITests */,
 				97C146EF1CF9000F007C117D /* Products */,
 				840012C8B5EDBCF56B0E4AC1 /* Pods */,
 				CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
@@ -161,6 +189,7 @@
 			children = (
 				97C146EE1CF9000F007C117D /* Runner.app */,
 				680049172280D368006DD6AB /* image_picker_exampleTests.xctest */,
+				6801C8362555D726009DAF8D /* RunnerUITests.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -218,6 +247,24 @@
 			productReference = 680049172280D368006DD6AB /* image_picker_exampleTests.xctest */;
 			productType = "com.apple.product-type.bundle.unit-test";
 		};
+		6801C8352555D726009DAF8D /* RunnerUITests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 6801C83F2555D726009DAF8D /* Build configuration list for PBXNativeTarget "RunnerUITests" */;
+			buildPhases = (
+				6801C8322555D726009DAF8D /* Sources */,
+				6801C8332555D726009DAF8D /* Frameworks */,
+				6801C8342555D726009DAF8D /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				6801C83C2555D726009DAF8D /* PBXTargetDependency */,
+			);
+			name = RunnerUITests;
+			productName = RunnerUITests;
+			productReference = 6801C8362555D726009DAF8D /* RunnerUITests.xctest */;
+			productType = "com.apple.product-type.bundle.ui-testing";
+		};
 		97C146ED1CF9000F007C117D /* Runner */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
@@ -255,6 +302,11 @@
 						ProvisioningStyle = Automatic;
 						TestTargetID = 97C146ED1CF9000F007C117D;
 					};
+					6801C8352555D726009DAF8D = {
+						CreatedOnToolsVersion = 11.7;
+						ProvisioningStyle = Automatic;
+						TestTargetID = 97C146ED1CF9000F007C117D;
+					};
 					97C146ED1CF9000F007C117D = {
 						CreatedOnToolsVersion = 7.3.1;
 						SystemCapabilities = {
@@ -280,6 +332,7 @@
 			targets = (
 				97C146ED1CF9000F007C117D /* Runner */,
 				680049162280D368006DD6AB /* image_picker_exampleTests */,
+				6801C8352555D726009DAF8D /* RunnerUITests */,
 			);
 		};
 /* End PBXProject section */
@@ -296,6 +349,13 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		6801C8342555D726009DAF8D /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		97C146EC1CF9000F007C117D /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -389,6 +449,14 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		6801C8322555D726009DAF8D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		97C146EA1CF9000F007C117D /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -407,6 +475,11 @@
 			target = 97C146ED1CF9000F007C117D /* Runner */;
 			targetProxy = 6800491C2280D368006DD6AB /* PBXContainerItemProxy */;
 		};
+		6801C83C2555D726009DAF8D /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 97C146ED1CF9000F007C117D /* Runner */;
+			targetProxy = 6801C83B2555D726009DAF8D /* PBXContainerItemProxy */;
+		};
 /* End PBXTargetDependency section */
 
 /* Begin PBXVariantGroup section */
@@ -480,9 +553,55 @@
 			};
 			name = Release;
 		};
+		6801C83D2555D726009DAF8D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
+				CODE_SIGN_STYLE = Automatic;
+				DEVELOPMENT_TEAM = "";
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				INFOPLIST_FILE = RunnerUITests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = com.google.RunnerUITests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TARGETED_DEVICE_FAMILY = "1,2";
+				TEST_TARGET_NAME = Runner;
+			};
+			name = Debug;
+		};
+		6801C83E2555D726009DAF8D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
+				CODE_SIGN_STYLE = Automatic;
+				DEVELOPMENT_TEAM = "";
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				INFOPLIST_FILE = RunnerUITests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MTL_FAST_MATH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = com.google.RunnerUITests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TARGETED_DEVICE_FAMILY = "1,2";
+				TEST_TARGET_NAME = Runner;
+			};
+			name = Release;
+		};
 		97C147031CF9000F007C117D /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
@@ -539,7 +658,6 @@
 		};
 		97C147041CF9000F007C117D /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
@@ -644,6 +762,15 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		6801C83F2555D726009DAF8D /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				6801C83D2555D726009DAF8D /* Debug */,
+				6801C83E2555D726009DAF8D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m
new file mode 100644
index 0000000..1ba8457
--- /dev/null
+++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m
@@ -0,0 +1,174 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <XCTest/XCTest.h>
+#import <os/log.h>
+
+const int kElementWaitingTime = 30;
+
+@interface ImagePickerFromGalleryUITests : XCTestCase
+
+@property(nonatomic, strong) XCUIApplication* app;
+
+@end
+
+@implementation ImagePickerFromGalleryUITests
+
+- (void)setUp {
+  // Delete the app if already exists, to test permission popups
+
+  self.continueAfterFailure = NO;
+  self.app = [[XCUIApplication alloc] init];
+  [self.app launch];
+  [self addUIInterruptionMonitorWithDescription:@"Permission popups"
+                                        handler:^BOOL(XCUIElement* _Nonnull interruptingElement) {
+                                          XCUIElement* ok = interruptingElement.buttons[@"OK"];
+                                          if (ok.exists) {
+                                            [ok tap];
+                                          }
+                                          // iOS 14.
+                                          XCUIElement* allPhotoPermission =
+                                              interruptingElement
+                                                  .buttons[@"Allow Access to All Photos"];
+                                          if (allPhotoPermission.exists) {
+                                            [allPhotoPermission tap];
+                                          }
+                                          return YES;
+                                        }];
+}
+
+- (void)testPickingFromGallery {
+  [self launchPickerAndCancel];
+  [self launchPickerAndPick];
+}
+
+- (void)launchPickerAndCancel {
+  // Find and tap on the pick from gallery button.
+  NSPredicate* predicateToFindImageFromGalleryButton =
+      [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_from_gallery"];
+
+  XCUIElement* imageFromGalleryButton =
+      [self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton];
+  if (![imageFromGalleryButton waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find image from gallery button with %@ seconds",
+            @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(imageFromGalleryButton.exists);
+  [imageFromGalleryButton tap];
+
+  // Find and tap on the `pick` button.
+  NSPredicate* predicateToFindPickButton =
+      [NSPredicate predicateWithFormat:@"label == %@", @"PICK"];
+
+  XCUIElement* pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton];
+  if (![pickButton waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find pick button with %@ seconds", @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(pickButton.exists);
+  [pickButton tap];
+
+  // There is a known bug where the permission popups interruption won't get fired until a tap
+  // happened in the app. We expect a permission popup so we do a tap here.
+  [self.app tap];
+
+  // Find and tap on the `Cancel` button.
+  NSPredicate* predicateToFindCancelButton =
+      [NSPredicate predicateWithFormat:@"label == %@", @"Cancel"];
+
+  XCUIElement* cancelButton =
+      [self.app.buttons elementMatchingPredicate:predicateToFindCancelButton];
+  if (![cancelButton waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find Cancel button with %@ seconds",
+            @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(cancelButton.exists);
+  [cancelButton tap];
+
+  // Find the "not picked image text".
+  XCUIElement* imageNotPickedText = [self.app.otherElements
+      elementMatchingPredicate:[NSPredicate
+                                   predicateWithFormat:@"label == %@",
+                                                       @"You have not yet picked an image."]];
+  if (![imageNotPickedText waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find imageNotPickedText with %@ seconds",
+            @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(imageNotPickedText.exists);
+}
+
+- (void)launchPickerAndPick {
+  // Find and tap on the pick from gallery button.
+  NSPredicate* predicateToFindImageFromGalleryButton =
+      [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_from_gallery"];
+
+  XCUIElement* imageFromGalleryButton =
+      [self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton];
+  if (![imageFromGalleryButton waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find image from gallery button with %@ seconds",
+            @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(imageFromGalleryButton.exists);
+  [imageFromGalleryButton tap];
+
+  // Find and tap on the `pick` button.
+  NSPredicate* predicateToFindPickButton =
+      [NSPredicate predicateWithFormat:@"label == %@", @"PICK"];
+
+  XCUIElement* pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton];
+  if (![pickButton waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find pick button with %@ seconds", @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(pickButton.exists);
+  [pickButton tap];
+
+  // Find an image and tap on it. (IOS 14 UI, images are showing directly)
+  XCUIElement* aImage;
+  if (@available(iOS 14, *)) {
+    aImage = self.app.scrollViews.firstMatch.images.firstMatch;
+  } else {
+    XCUIElement* allPhotosCell = [self.app.cells
+        elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"All Photos"]];
+    if (![allPhotosCell waitForExistenceWithTimeout:kElementWaitingTime]) {
+      os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+      XCTFail(@"Failed due to not able to find \"All Photos\" cell with %@ seconds",
+              @(kElementWaitingTime));
+    }
+    [allPhotosCell tap];
+    aImage = [self.app.collectionViews elementMatchingType:XCUIElementTypeCollectionView
+                                                identifier:@"PhotosGridView"]
+                 .cells.firstMatch;
+  }
+  if (![aImage waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kElementWaitingTime));
+  }
+  XCTAssertTrue(aImage.exists);
+  [aImage tap];
+
+  // Find the picked image.
+  NSPredicate* predicateToFindPickedImage =
+      [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_picked_image"];
+
+  XCUIElement* pickedImage = [self.app.images elementMatchingPredicate:predicateToFindPickedImage];
+  if (![pickedImage waitForExistenceWithTimeout:kElementWaitingTime]) {
+    os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
+    XCTFail(@"Failed due to not able to find pickedImage with %@ seconds", @(kElementWaitingTime));
+  }
+
+  XCTAssertTrue(pickedImage.exists);
+}
+
+@end
diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/Info.plist b/packages/image_picker/image_picker/example/ios/RunnerUITests/Info.plist
new file mode 100644
index 0000000..64d65ca
--- /dev/null
+++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>
diff --git a/packages/image_picker/image_picker/example/lib/main.dart b/packages/image_picker/image_picker/example/lib/main.dart
index ece8c45..3047ac1 100755
--- a/packages/image_picker/image_picker/example/lib/main.dart
+++ b/packages/image_picker/image_picker/example/lib/main.dart
@@ -156,7 +156,9 @@
         // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform
         return Image.network(_imageFile.path);
       } else {
-        return Image.file(File(_imageFile.path));
+        return Semantics(
+            child: Image.file(File(_imageFile.path)),
+            label: 'image_picker_example_picked_image');
       }
     } else if (_pickImageError != null) {
       return Text(
@@ -231,14 +233,17 @@
       floatingActionButton: Column(
         mainAxisAlignment: MainAxisAlignment.end,
         children: <Widget>[
-          FloatingActionButton(
-            onPressed: () {
-              isVideo = false;
-              _onImageButtonPressed(ImageSource.gallery, context: context);
-            },
-            heroTag: 'image0',
-            tooltip: 'Pick Image from gallery',
-            child: const Icon(Icons.photo_library),
+          Semantics(
+            label: 'image_picker_example_from_gallery',
+            child: FloatingActionButton(
+              onPressed: () {
+                isVideo = false;
+                _onImageButtonPressed(ImageSource.gallery, context: context);
+              },
+              heroTag: 'image0',
+              tooltip: 'Pick Image from gallery',
+              child: const Icon(Icons.photo_library),
+            ),
           ),
           Padding(
             padding: const EdgeInsets.only(top: 16.0),
diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml
index 711d2db..2dcd7c1 100755
--- a/packages/image_picker/image_picker/pubspec.yaml
+++ b/packages/image_picker/image_picker/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin for selecting images from the Android and iOS image
   library, and taking new pictures with the camera.
 homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
-version: 0.6.7+13
+version: 0.6.7+14
 
 flutter:
   plugin: