Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[image_picker] Set up XCUITests #3254

Merged
merged 7 commits into from
Nov 9, 2020

Conversation

cyanglaz
Copy link
Contributor

@cyanglaz cyanglaz commented Nov 6, 2020

Description

Set up the XCUITests harness for image picker plugin

Related Issues

Help with flutter/flutter#65995 (This is not a fix, this only sets up tests so it is easier to write tests when fixing the issue)

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See Contributor Guide).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the Flutter Style Guide.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the CLA.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

@google-cla google-cla bot added the cla: yes label Nov 6, 2020
@cyanglaz cyanglaz requested review from jmagman and amirh November 6, 2020 21:39
XCUIElement* aImage = self.app.scrollViews.firstMatch.images.firstMatch;
XCUIElement* allPhotosCell = [self.app.cells
elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"All Photos"]];
XCUIElement* firstExist = [RunnerUITestUtils waitForFirstExistence:@[ aImage, allPhotosCell ]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The waitForFirstExistence function worries me a little bit as it is non deterministic, and performing a busy-wait.
What do you think about checking for the OS version here, and use it to determine if we need to wait for the allPhotosCell?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

@jmagman jmagman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits

XCUIElement* aImage = self.app.scrollViews.firstMatch.images.firstMatch;
XCUIElement* allPhotosCell = [self.app.cells
elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"All Photos"]];
XCUIElement* firstExist = [RunnerUITestUtils waitForFirstExistence:@[ aImage, allPhotosCell ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels heavy (and the check should probably be scheduled on a runloop instead of the while). Can you instead check if (@available(iOS 14.0, *)) directly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, ditto what @amirh said, didn't see his comment until I submitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCTAssertTrue(pickButton.exists);
[pickButton tap];

// Find an image and tap on it. (IOS 14 UI, images are showing direclty)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

directly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCUIElement* pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton];
if (![pickButton waitForExistenceWithTimeout:30]) {
NSLog(@"%@", self.app.debugDescription);
XCTFail(@"Failed due to not able to find pick button with %@ seconds", @(30));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're going to hard code it anyway, can do @"Failed due to not able to find pick button with 30 seconds". Or format as an int. Don't need the NSNumber here but if you do use it, number literals don't need the parentheses, @30.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCUIElement* imageFromGalleryButton =
[self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton];
if (![imageFromGalleryButton waitForExistenceWithTimeout:30]) {
NSLog(@"%@", self.app.debugDescription);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NSLog is soft deprecated, should prefer os_log.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor Author

@cyanglaz cyanglaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amirh @jmagman Thanks for the quick review! Updated per comments. PTAL

XCUIElement* imageFromGalleryButton =
[self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton];
if (![imageFromGalleryButton waitForExistenceWithTimeout:30]) {
NSLog(@"%@", self.app.debugDescription);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCUIElement* pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton];
if (![pickButton waitForExistenceWithTimeout:30]) {
NSLog(@"%@", self.app.debugDescription);
XCTFail(@"Failed due to not able to find pick button with %@ seconds", @(30));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCTAssertTrue(pickButton.exists);
[pickButton tap];

// Find an image and tap on it. (IOS 14 UI, images are showing direclty)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCUIElement* aImage = self.app.scrollViews.firstMatch.images.firstMatch;
XCUIElement* allPhotosCell = [self.app.cells
elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"All Photos"]];
XCUIElement* firstExist = [RunnerUITestUtils waitForFirstExistence:@[ aImage, allPhotosCell ]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

XCUIElement* aImage = self.app.scrollViews.firstMatch.images.firstMatch;
XCUIElement* allPhotosCell = [self.app.cells
elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"All Photos"]];
XCUIElement* firstExist = [RunnerUITestUtils waitForFirstExistence:@[ aImage, allPhotosCell ]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

@jmagman jmagman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@amirh amirh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cyanglaz cyanglaz merged commit 4e8f8ed into flutter:master Nov 9, 2020
@cyanglaz cyanglaz deleted the image_picker_uitests branch November 9, 2020 21:01
@@ -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 */; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amirh This is the new test file that Chris added. If Xcode doesn't know about it, then xcodebuild test won't run it.

@@ -34,6 +35,13 @@
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
6801C83B2555D726009DAF8D /* PBXContainerItemProxy */ = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new test target. This grouping tells Xcode what kind of tests they are (UI tests in this case) so it knows how to run them.

@@ -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; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the location the test xctest product bundle will be built, so the binaries where the tests are compiled into.

@@ -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>"; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new test file that was explicitly added.

@@ -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>"; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Info.plist file that was also explicitly added. It contains metadata about the bundle, and is required for most bundle types (apps, frameworks, extensions etc)

@@ -389,6 +449,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
6801C8322555D726009DAF8D /* Sources */ = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Sources build phase that says which files should be compiled into the xctest bundle. So ImagePickerFromGalleryUITests in this case.

@@ -407,6 +475,11 @@
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 6800491C2280D368006DD6AB /* PBXContainerItemProxy */;
};
6801C83C2555D726009DAF8D /* PBXTargetDependency */ = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This says that the test target depends on the Runner (app) target, so Runner needs to be built first.

@@ -480,9 +553,55 @@
};
name = Release;
};
6801C83D2555D726009DAF8D /* Debug */ = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the Debug build configuration build settings, and it looks like it's all the defaults Xcode uses for new targets. The CLANG_ GCC_C_ and MTL_ ones can be removed since they would be inherited from the overall project settings. But most people just let Xcode set the overrides it wants and don't touch it.

};
name = Debug;
};
6801C83E2555D726009DAF8D /* Release */ = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto but for the Release build configuration build settings.

@@ -644,6 +762,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6801C83F2555D726009DAF8D /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This the hook for setting build configuration settings for the new test target (like a base xcconfig file)

fesp pushed a commit to fesp/plugins that referenced this pull request Nov 11, 2020
FlutterSu pushed a commit to FlutterSu/flutter-plugins that referenced this pull request Nov 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants